Muchas aplicaciones necesitan conservar información después de cerrar el programa. Una lista en memoria desaparece al terminar el proceso, mientras que una base de datos mantiene registros estructurados y permite buscarlos, actualizarlos y relacionarlos. SQLite con Python es una excelente primera opción porque funciona dentro de la aplicación, guarda los datos en un único archivo y está disponible mediante la biblioteca estándar.
En esta guía crearás una pequeña base de tareas y aprenderás conexiones, tablas, parámetros, transacciones, consultas, actualizaciones y eliminación segura. No necesitas instalar ni administrar un servidor independiente.
Qué es SQLite
SQLite es un motor de base de datos relacional integrado. En lugar de conectarse a un proceso remoto, tu programa abre un archivo local. Es útil para herramientas de escritorio, prototipos, aplicaciones de terminal, pruebas y muchos proyectos pequeños o medianos.
Python incluye el módulo sqlite3. Antes de continuar, puede resultar útil repasar el manejo de diccionarios en Python, ya que más adelante convertiremos filas en estructuras con nombres.
Crear y conectar una base de datos
import sqlite3
with sqlite3.connect("tareas.db") as conexion:
conexion.execute("""
CREATE TABLE IF NOT EXISTS tareas (
id INTEGER PRIMARY KEY,
titulo TEXT NOT NULL,
completada INTEGER NOT NULL DEFAULT 0
)
""")sqlite3.connect() abre el archivo existente o lo crea. El context manager confirma el trabajo cuando todo termina correctamente y revierte la transacción cuando una excepción sale del bloque.
Insertar datos con parámetros
No construyas SQL con f-strings ni concatenando valores del usuario. Los marcadores separan las instrucciones de los datos y evitan problemas de comillas e inyección SQL.
import sqlite3
titulo = "Revisar documentación"
with sqlite3.connect("tareas.db") as conexion:
conexion.execute(
"INSERT INTO tareas (titulo) VALUES (?)",
(titulo,),
)La coma en (titulo,) crea una tupla de un elemento. Para insertar varias filas utiliza executemany().
tareas = [
("Escribir pruebas",),
("Preparar informe",),
("Actualizar dependencias",),
]
with sqlite3.connect("tareas.db") as conexion:
conexion.executemany(
"INSERT INTO tareas (titulo) VALUES (?)",
tareas,
)La validación y el control de errores se explican con más detalle en la guía de try y except en Python.
Consultar registros
import sqlite3
with sqlite3.connect("tareas.db") as conexion:
cursor = conexion.execute(
"SELECT id, titulo, completada FROM tareas ORDER BY id"
)
for tarea_id, titulo, completada in cursor:
estado = "hecha" if completada else "pendiente"
print(tarea_id, titulo, estado)Un SELECT devuelve un cursor. Puedes recorrerlo, llamar a fetchone() o recuperar todos los resultados con fetchall(). La iteración es preferible cuando el conjunto puede ser grande.
Filas con acceso por nombre
import sqlite3
with sqlite3.connect("tareas.db") as conexion:
conexion.row_factory = sqlite3.Row
fila = conexion.execute(
"SELECT id, titulo, completada FROM tareas WHERE id = ?",
(1,),
).fetchone()
if fila is not None:
print(fila["titulo"])fetchone() devuelve None cuando no hay coincidencias. La guía de None en Python explica por qué debes comprobarlo explícitamente.
Actualizar registros
import sqlite3
with sqlite3.connect("tareas.db") as conexion:
conexion.execute(
"UPDATE tareas SET completada = 1 WHERE id = ?",
(2,),
)Revisa siempre la cláusula WHERE. Omitirla modifica todas las filas de la tabla.
Eliminar registros
import sqlite3
with sqlite3.connect("tareas.db") as conexion:
conexion.execute(
"DELETE FROM tareas WHERE id = ?",
(3,),
)En operaciones destructivas conviene seleccionar primero el registro, mostrarlo y solicitar confirmación.
Filtrar y buscar con SQL
import sqlite3
busqueda = "prueba"
with sqlite3.connect("tareas.db") as conexion:
filas = conexion.execute(
"""
SELECT id, titulo
FROM tareas
WHERE completada = 0
AND titulo LIKE ?
ORDER BY titulo
""",
(f"%{busqueda}%",),
).fetchall()
print(filas)Los porcentajes son comodines de LIKE, pero el valor sigue enviándose como parámetro. Para ordenar colecciones que ya están en memoria, consulta sort() y sorted() en Python.
Transacciones
Una transacción agrupa cambios relacionados. O todos se confirman o ninguno debería permanecer.
import sqlite3
def completar_y_crear(tarea_id, nuevo_titulo):
with sqlite3.connect("tareas.db") as conexion:
conexion.execute(
"UPDATE tareas SET completada = 1 WHERE id = ?",
(tarea_id,),
)
conexion.execute(
"INSERT INTO tareas (titulo) VALUES (?)",
(nuevo_titulo,),
)Las transacciones son esenciales cuando un cambio parcial dejaría datos inconsistentes, como pedidos, inventario o movimientos financieros.
Crear una clase de acceso
import sqlite3
class RepositorioTareas:
def __init__(self, base="tareas.db"):
self.base = base
def agregar(self, titulo):
with sqlite3.connect(self.base) as conexion:
cursor = conexion.execute(
"INSERT INTO tareas (titulo) VALUES (?)",
(titulo,),
)
return int(cursor.lastrowid)
def listar_pendientes(self):
with sqlite3.connect(self.base) as conexion:
return conexion.execute(
"""
SELECT id, titulo
FROM tareas
WHERE completada = 0
ORDER BY id
"""
).fetchall()Separar las consultas de la interfaz facilita las pruebas y evita mezclar SQL con menús o formularios.
Guardar fechas
SQLite no impone un único tipo para fechas. Una estrategia frecuente es guardar texto ISO 8601 o marcas de tiempo y convertirlas en Python. Revisa la guía de datetime en Python para mantener formatos coherentes.
Errores frecuentes
- Construir SQL con datos del usuario.
- Olvidar confirmar cambios o entender los límites de una transacción.
- Usar
fetchall()con resultados enormes. - No comprobar si
fetchone()devolvióNone. - Ejecutar
UPDATEoDELETEsin revisarWHERE. - Compartir una conexión de forma insegura entre hilos.
- Guardar fechas con formatos inconsistentes.
Cuándo elegir otra base de datos
SQLite no sustituye a todos los servidores. Una aplicación con muchos escritores simultáneos, administración centralizada de usuarios, replicación o cargas operativas muy grandes puede necesitar PostgreSQL, MySQL u otro sistema cliente-servidor.
Conclusión
SQLite con Python es un puente práctico entre scripts en memoria y aplicaciones persistentes. Define un esquema claro, utiliza parámetros, agrupa cambios relacionados en transacciones y separa las operaciones de base de datos de la interfaz.
Documentación oficial
Para profundizar, consulta la documentación oficial de Python sobre el módulo sqlite3 y la referencia oficial del lenguaje SQL de SQLite.






