SQLite es una librería que proporciona un sistema de gestión de bases de datos (SGBD) relacional y se incluye con Python de forma predeterminada. Es una base de datos extremadamente liviana, eficiente y fácil de usar, lo que la hace ideal para aplicaciones pequeñas o medianas que requieren almacenamiento local de datos. A continuación mostraremos cómo utilizar SQLite en Python, con explicaciones y ejemplos prácticos.
Instalación
Python incluye SQLite como parte de la biblioteca estándar, por lo que no es necesario instalar nada adicional para comenzar a trabajar con SQLite en Python.
Conexión a la base de datos
Antes de interactuar con la base de datos, necesitamos establecer una conexión. Para ello, utilizamos el módulo sqlite3
que viene integrado con Python:
import sqlite3 # Crear una conexión o conectarse a una base de datos existente (si no existe, se creará) conexion = sqlite3.connect("mi_base_de_datos.db")
Crear una tabla
Después de establecer la conexión, ya podemos crear una tabla en la base de datos. Para ello, necesitamos un objeto «cursor» que nos permitirá ejecutar comandos SQL:
# Obtener un objeto cursor cursor = conexion.cursor() # Crear una tabla cursor.execute("CREATE TABLE IF NOT EXISTS usuarios (id INTEGER PRIMARY KEY, nombre TEXT, edad INTEGER)")
Insertar datos
Podemos insertar datos en una tabla utilizando el método execute()
para ejecutar un comando SQL de inserción:
# Insertar datos en la tabla cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('Juan', 30)") cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('María', 25)") # Guardar los cambios (commit) en la base de datos conexion.commit()
Consultar datos
Para obtener datos de una tabla, podemos utilizar el método execute()
para ejecutar una consulta SQL de selección y luego utilizar los métodos fetchone()
o fetchall()
para obtener los resultados:
# Consultar datos de la tabla cursor.execute("SELECT * FROM usuarios") # Obtener un solo resultado primer_usuario = cursor.fetchone() print(primer_usuario) # Salida: (1, 'Juan', 30) # Obtener todos los resultados todos_los_usuarios = cursor.fetchall() print(todos_los_usuarios) # Salida: [(1, 'Juan', 30), (2, 'María', 25)]
Actualizar datos
Para actualizar los datos de una tabla también usaremos el método execute()
, utilizando en este caso como parámetro un comando SQL de actualización:
# Actualizar datos en la tabla cursor.execute("UPDATE usuarios SET edad = 31 WHERE nombre = 'Juan'") # Guardar los cambios (commit) en la base de datos conexion.commit()
Eliminar datos
Para eliminar datos de una tabla, también haremos uso del método execute()
utilizando un comando SQL de eliminación:
# Eliminar datos de la tabla cursor.execute("DELETE FROM usuarios WHERE nombre = 'María'") # Guardar los cambios (commit) en la base de datos conexion.commit()
Cerrar la conexión
Es importante cerrar la conexión una vez que hayamos terminado de trabajar con la base de datos:
# Cerrar la conexión conexion.close()
Transacciones
Las transacciones son bloques de operaciones que se ejecutan como una sola unidad. SQLite permite trabajar con transacciones para asegurar la integridad de los datos. Las transacciones se inician con BEGIN
y se confirman con COMMIT
. Si algo sale mal, se pueden revertir con ROLLBACK
.
Veamos un ejemplo a continuación. Si todas las operaciones dentro de la transacción se realizan correctamente, se confirman las inserciones de los nuevos registros y los cambios se guardan en la base de datos. Si alguna operación falla, los inserciones se revierten y no se realizan cambios en la base de datos:
import sqlite3 conexion = sqlite3.connect("mi_base_de_datos.db") cursor = conexion.cursor() # Iniciar transacción cursor.execute("BEGIN") try: # Realizar operaciones en la base de datos cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('Ana', 28)") cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('Pedro', 35)") # ... más operaciones SQL ... # Confirmar transacción cursor.execute("COMMIT") print("Transacción exitosa") except Exception as e: # Revertir transacción en caso de error cursor.execute("ROLLBACK") print("Error en la transacción:", e) conexion.close()
Consultas parametrizadas
Es recomendable utilizar consultas parametrizadas para evitar la inyección de SQL y mejorar la seguridad de nuestras aplicaciones. Las consultas parametrizadas se crean mediante el método execute()
y los valores que se utilizan se pueden pasar como una tupla o un diccionario:
# Consulta parametrizada con tupla nombre = "Luis" edad = 40 cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES (?, ?)", (nombre, edad)) # Consulta parametrizada con diccionario usuario = {"nombre": "Sofía", "edad": 27} cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES (:nombre, :edad)", usuario)
Ejemplo completo con una tabla
A continuación mostramos un ejemplo completo que resume todas las operaciones que hemos visto:
import sqlite3 # Conexión a la base de datos conexion = sqlite3.connect("mi_base_de_datos.db") cursor = conexion.cursor() # Crear tabla si no existe cursor.execute("CREATE TABLE IF NOT EXISTS usuarios (id INTEGER PRIMARY KEY, nombre TEXT, edad INTEGER)") # Insertar datos cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('Juan', 30)") cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('María', 25)") # Consultar datos cursor.execute("SELECT * FROM usuarios") todos_los_usuarios = cursor.fetchall() print(todos_los_usuarios) # Salida: [(1, 'Juan', 30), (2, 'María', 25)] # Actualizar datos cursor.execute("UPDATE usuarios SET edad = 31 WHERE nombre = 'Juan'") cursor.execute("SELECT * FROM usuarios") todos_los_usuarios = cursor.fetchall() print(todos_los_usuarios) # Salida: [(1, 'Juan', 31), (2, 'María', 25)] # Eliminar datos cursor.execute("DELETE FROM usuarios WHERE nombre = 'María'") cursor.execute("SELECT * FROM usuarios") todos_los_usuarios = cursor.fetchall() print(todos_los_usuarios) # Salida: [(1, 'Juan', 31)] # Cerrar conexión conexion.close()
Creación de múltiples tablas
SQLite ofrece muchas más funcionalidades, como la capacidad de trabajar con múltiples tablas, realizar consultas complejas, utilizar funciones agregadas y trabajar con claves ajenas para establecer relaciones entre tablas.
Para crear múltiples tablas en una base de datos SQLite, simplemente debemos ejecutar múltiples comandos CREATE TABLE
. Cada tabla se crea con su propia estructura y columnas:
import sqlite3 conexion = sqlite3.connect("mi_base_de_datos.db") cursor = conexion.cursor() # Crear una tabla de usuarios cursor.execute("CREATE TABLE IF NOT EXISTS usuarios (id INTEGER PRIMARY KEY, nombre TEXT, edad INTEGER)") # Crear una tabla de productos cursor.execute("CREATE TABLE IF NOT EXISTS productos (id INTEGER PRIMARY KEY, nombre TEXT, precio REAL)") conexion.close()
Relaciones entre tablas y claves ajenas
SQLite permite definir claves ajenas para establecer relaciones entre los registros de dos o más tablas. En el siguiente ejemplo crearemos una tabla de «pedidos» que tiene una clave ajena que nos permite llegar a la tabla de «usuarios»:
import sqlite3 conexion = sqlite3.connect("mi_base_de_datos.db") cursor = conexion.cursor() # Crear tabla de usuarios cursor.execute("CREATE TABLE IF NOT EXISTS usuarios (id INTEGER PRIMARY KEY, nombre TEXT, edad INTEGER)") # Crear tabla de pedidos con clave ajena cursor.execute("CREATE TABLE IF NOT EXISTS pedidos (id INTEGER PRIMARY KEY, usuario_id INTEGER, fecha TEXT, FOREIGN KEY (usuario_id) REFERENCES usuarios(id))") conexion.close()
Consultas más complejas
SQLite permite realizar consultas SQL más complejas utilizando cláusulas JOIN, GROUP BY, HAVING, ORDER BY, y otras. Por ejemplo, supongamos que tenemos una tabla «ventas» que contiene información sobre las ventas realizadas en una empresa, relacionando los productos que se han vendido con los usuarios que los han comprado. En este caso, podemos llegar a obtener información sobre el total de ventas por producto utilizando la cláusula GROUP BY
y la función agregada SUM
:
import sqlite3 conexion = sqlite3.connect("mi_base_de_datos.db") cursor = conexion.cursor() # Crear tabla de usuarios cursor.execute("CREATE TABLE IF NOT EXISTS usuarios (id INTEGER PRIMARY KEY, nombre TEXT, edad INTEGER)") # Crear tabla de productos cursor.execute("CREATE TABLE IF NOT EXISTS productos (id INTEGER PRIMARY KEY, nombre TEXT, precio REAL)") # Crear tabla de ventas cursor.execute("CREATE TABLE IF NOT EXISTS ventas (id INTEGER PRIMARY KEY, usuario_id INTEGER, producto_id INTEGER, cantidad INTEGER)") # Insertar datos de ejemplo cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('Juan', 30)") cursor.execute("INSERT INTO usuarios (nombre, edad) VALUES ('María', 25)") cursor.execute("INSERT INTO productos (nombre, precio) VALUES ('Producto A', 10.5)") cursor.execute("INSERT INTO productos (nombre, precio) VALUES ('Producto B', 20.0)") cursor.execute("INSERT INTO ventas (usuario_id, producto_id, cantidad) VALUES (1, 1, 3)") cursor.execute("INSERT INTO ventas (usuario_id, producto_id, cantidad) VALUES (2, 2, 2)") cursor.execute("INSERT INTO ventas (usuario_id, producto_id, cantidad) VALUES (1, 2, 1)") # Consulta para obtener el total de ventas por producto cursor.execute("SELECT productos.nombre, SUM(ventas.cantidad) FROM ventas JOIN productos ON ventas.producto_id = productos.id GROUP BY productos.nombre") resultado = cursor.fetchall() print(resultado) # [('Producto A', 3), ('Producto B', 3)] conexion.close()
Test
Evalúa tus conocimientos mediante este test que incluye preguntas relacionadas con esta unidad.