Bases de datos y SQL desde cero, con SQLite
Tablas, claves y las consultas SQL que más se usan, practicando con SQLite sin instalar un servidor.
Casi todas las aplicaciones guardan datos: usuarios, pedidos, mensajes, puntuaciones. Para eso se usan bases de datos, y la mayoría de las clásicas son relacionales: guardan los datos en tablas relacionadas entre sí y se consultan con SQL (Structured Query Language). SQL se parece mucho en MySQL, PostgreSQL, SQL Server o SQLite, así que lo que aprendas aquí te sirve en todas.
Tablas, filas y claves
Una tabla es como una hoja de cálculo con reglas estrictas:
- Cada columna tiene un nombre y un tipo (texto, número entero, decimal, fecha…).
- Cada fila es un registro: un alumno, un pedido.
- La clave primaria identifica cada fila sin repetirse (normalmente un número
id). - Una clave foránea es una columna que apunta a la clave primaria de otra tabla y crea la relación: cada nota pertenece a un alumno.
Separar los datos en tablas evita repetirlos: el nombre del alumno se guarda una vez, no en cada nota.
Practicar con SQLite sin instalar un servidor
SQLite guarda toda la base de datos en un único archivo y Python la incluye de serie en el módulo sqlite3. Este programa crea dos tablas y las rellena:
import sqlite3
con = sqlite3.connect("instituto.db")
cur = con.cursor()
cur.executescript("""
CREATE TABLE IF NOT EXISTS alumnos (
id INTEGER PRIMARY KEY,
nombre TEXT NOT NULL,
curso TEXT
);
CREATE TABLE IF NOT EXISTS notas (
id INTEGER PRIMARY KEY,
alumno_id INTEGER REFERENCES alumnos(id),
asignatura TEXT,
nota REAL
);
""")
cur.executemany("INSERT INTO alumnos (nombre, curso) VALUES (?, ?)",
[("Lucía", "1.º DAM"), ("Omar", "1.º DAM"), ("Sara", "2.º DAW")])
cur.executemany("INSERT INTO notas (alumno_id, asignatura, nota) VALUES (?, ?, ?)",
[(1, "Programación", 8.5), (2, "Programación", 6), (3, "Bases de datos", 9)])
con.commit()
commit() confirma los cambios; sin él, no se guardan en el archivo.
Las consultas que más vas a usar
-- Leer: columnas, de qué tabla y con qué condición
SELECT nombre, curso FROM alumnos WHERE curso = '1.º DAM' ORDER BY nombre;
-- Contar y agrupar
SELECT curso, COUNT(*) AS total FROM alumnos GROUP BY curso;
-- Modificar (¡siempre con WHERE!)
UPDATE notas SET nota = 7 WHERE id = 2;
-- Borrar (¡siempre con WHERE!)
DELETE FROM notas WHERE id = 3;
Un UPDATE o un DELETE sin WHERE afecta a todas las filas de la tabla. Antes de ejecutarlos, prueba la misma condición con un SELECT para ver qué filas vas a tocar.
JOIN: unir tablas
Para ver el nombre del alumno junto a cada nota hay que unir las dos tablas por su relación:
SELECT alumnos.nombre, notas.asignatura, notas.nota
FROM notas
JOIN alumnos ON alumnos.id = notas.alumno_id
WHERE notas.nota >= 5;
Desde Python, recorres el resultado así:
for nombre, asignatura, nota in cur.execute("""
SELECT alumnos.nombre, notas.asignatura, notas.nota
FROM notas JOIN alumnos ON alumnos.id = notas.alumno_id"""):
print(nombre, asignatura, nota)
La regla de seguridad más importante: parámetros, nunca texto pegado
Fíjate en los ? de los ejemplos. Nunca construyas una consulta pegando texto que viene del usuario:
# MAL: si alguien escribe ' OR '1'='1 verá todos los registros
cur.execute(f"SELECT * FROM alumnos WHERE nombre = '{texto}'")
# BIEN: el valor viaja aparte y nunca se interpreta como SQL
cur.execute("SELECT * FROM alumnos WHERE nombre = ?", (texto,))
Eso se llama inyección SQL y sigue estando entre los fallos de seguridad más graves de las aplicaciones. La documentación de sqlite3 de Python lo advierte expresamente. Lo verás con más detalle en la guía de seguridad al programar.
Siguientes pasos
- Para explorar un archivo
.dbsin programar, SQLite ofrece una herramienta de línea de comandos oficial (sqlite3) en sqlite.org. - Cuando una aplicación tiene muchos usuarios a la vez, se suele pasar a un servidor como PostgreSQL o MySQL; el SQL que has aprendido sigue valiendo.
- Practica diseñando la base de datos de algo que conozcas: tu biblioteca, una liga de fútbol o las tareas de clase.
Fuentes consultadas
- sqlite3: interfaz DB-API 2.0 para bases de datos SQLite (Python Software Foundation)
- SELECT (SQLite)
- Command Line Shell For SQLite (SQLite)
