PeeWee es un ORM “ligero” que nos permite interactuar con bases de datos SQLite, MySQL, PostgreSQL y CockroachDB. En este post haremos un CRUD básico con esta librería para conocer un poco más esta herramienta muy útil dentro del mundo de Python. Nuestros ejemplos, además, los haremos utilizando como base de datos SQLite.

La documentación de PeeWee está bastante completa y nos indica con ejemplos cómo utilizar este módulo en detalle. PeeWee es como SQLAlchemy, un ORN más “ligero” y “sencillo” de utilizar; con él podemos crear un modelo, insertar datos, consultar datos y por supuesto actualizar y eliminar los datos previamente introducidos. Soporta el uso de JOIN, claves foráneas y claves primarias compuestas.

Te mostramos dos tablas con los pros y contras de PeeWee y SQLAlchemy de pros y contras:

PeeWee:

PRO CON
Es más simple No es escalable
Si conoce Django se hace más familiar
Es bastante pequeño y de fácil uso
Buena documentación

SQLAlchemy:

PRO CON
Trabaja con cualquier Framework (Framework Agnóstico) Complejo de utilizar
Muy buena documentación
Mantenimiento activo
Gran comunidad

Por dónde empezar

Asumimos que tienes instalado lo siguiente en tu ordenador:

Sigamos con el CRUD básico basado en SQLite para que veamos cómo trabajar con PeeWee.

Lo primero es instalar el módulo en nuestro ordenador. Para ello ejecutamos el siguiente comando en nuestra consola:


pip install peewee

Ya instalado el módulo de PeeWee vamos a crear un modelo basado en este diagrama de base de datos:

El modelo lo creamos de la siguiente manera:

from peewee import SqliteDatabase, AutoField, CharField, DateField, ForeignKeyField, Model

db = SqliteDatabase('academia.db')

class Profesores(Model):
   maestro_id = AutoField()
   nombre = CharField()
   apellido = CharField()
   telefono = CharField()
   email = CharField(unique=True)

   class Meta:
       database = db

class Clases(Model):
   clase_id = AutoField()
   cod_curso = CharField()
   fecha_inicio_curso = DateField()
   fecha_fin_curso = DateField()
   horario = CharField()
   maestro_id = ForeignKeyField(Profesores)

   class Meta:
       database = db

db.connect()
db.create_tables([Profesores, Clases])

Vamos a explicar por paso cada una de las entradas importantes:

from peewee import SqliteDatabase, AutoField, CharField, DateField, ForeignKeyField, Model

Importamos PeeWee con todas sus librerías:

db = SqliteDatabase('academia.db')

Instanciamos la base de datos de SQLIte guardando la info en un fichero llamado ‘academia.db. Luego, colocamos como ejemplo la conexión con MySQL y con PostgreSQL:

mysql_db = MySQLDatabase(‘academia’, user=’root’, password=’my_password’, host=’localhost’, port=3306)

En este caso ‘academia’ es el nombre de la base de datos a conectar, ‘root’ el usuario con el que nos conectamos a MySQL, ‘my_password’ la clave de conexión, ‘localhost’ la dirección del host de MySQL y ‘3306’ el puerto TCP de MySQL.

pg_db = PostgresqlDatabase(‘academia’, user=’postgres’, password=’my_password’, host=’localhost’, port=5432)

Aquí ‘academia’ es el nombre de la base de datos a conectar, ‘postgres’ el usuario con el que nos conectamos a PostgreSQL, ‘my_password’ la clave de conexión, ‘localhost’ la dirección del host de PostgreSQL y ‘5432’ el puerto TCP de PostgreSQL.

class Profesores(Model):
   maestro_id = AutoField()
   nombre = CharField()
   apellido = CharField()
   telefono = CharField()
   email = CharField(unique=True)

   class Meta:
       database = db

Entonces, declaramos la primera tabla llamada “Profesores” heredado de “Model”. El nombre de la clase será el nombre de nuestra tabla dentro de la base de datos.

Por si acaso, te doy una breve explicación de los siguientes campos:

Luego tenemos la clase privada de Meta que es un “préstamo” de la clase Meta de Django, en él podemos declarar cualquier cosa que no sea un campo. Como, por ejemplo, la base de datos con que trabajará nuestro modelo (db), claves primarias complejas y nombre de tabla diferente al modelo declarado de la clase. Tienes más información aquí.

Para el modelo de “Clases” tenemos el siguiente código:

class Clases(Model):
   clase_id = AutoField()
   cod_curso = CharField()
   fecha_inicio_curso = DateField()
   fecha_fin_curso = DateField()
   horario = CharField()
   maestro_id = ForeignKeyField(Profesores)

   class Meta:
       database = db

Ahora declaramos la tabla de “Clases”, que igualmente heredamos de modelo, y las diferencias con lo que hemos visto antes son las siguientes:

Aquí hay más información sobre los tipos de campos soportados en PeeWee y sus iguales en SQLIte, MySQL y PostgreSQL.

Con esto nos conectamos a la base de datos:

db.connect()

Creamos las tablas de los modelos anteriormente declarado. Hay que destacar que los nombres de los modelos tenemos que pasarlos como lista, aunque sea solamente un solo modelo:

db.create_tables([Profesores, Clases])

INSERT

Ahora vamos a insertar nuestro primer registro en el modelo de “Profesores”:

chamo = Profesores( nombre='Chamo',
                   apellido='Linares',
                   telefono='640568923',
                   email='alinares@paradigmadigital.com')
chamo.save()

El modelo se basa en el paradigma orientado a objetos y es por ello que instanciamos en la variable chamo los datos que insertamos en la tabla. Para poder “aplicar” esto utilizamos el método save().

curso_python = Clases( cod_curso='python_101',
                    fecha_inicio_curso='2020-03-09',
                    fecha_fin_curso='2020-03-20',
                    horario='Matutino',
                    maestro_id = 1)
curso_python.save()

Ahora insertamos un curso dentro de la tabla “Clases”, agregamos la información de los campos correspondientes, destacando que el maestro_id es una clave foránea y debe estar previamente creado el maestro_id en la tabla de “Profesores”.

Podemos insertar más de un registro a la vez utilizando los métodos de atomic() y insert_many():

data = [
   {'cod_curso': 'python_202', 'fecha_inicio_curso': '2020-04-06', 'fecha_fin_curso': '2020-04-10', 'horario': 'Nocturno', 'maestro_id': 1},
   {'cod_curso': 'go_101', 'fecha_inicio_curso': '2020-04-13', 'fecha_fin_curso': '2020-04-17', 'horario': 'Matutitno', 'maestro_id': 1},
   {'cod_curso': 'linux_101', 'fecha_inicio_curso': '2020-04-20', 'fecha_fin_curso': '2020-04-24', 'horario': 'Vespertino', 'maestro_id': 1},
]

with db.atomic():
   query = Clases.insert_many(data)
   query.execute()

SELECT

Para hacer una consulta sencilla de la tabla de Profesores hacemos lo siguiente:

for profesor in Profesores.select():
     print('Nombre: {} - Apellido: {} - Teléfono: {} - Email: {}'
     .format(profesor.nombre, profesor.apellido, profesor.telefono, profesor.email))

Ahora para hacer una consulta donde listamos los cursos actuales de un profesor hacemos lo siguiente:

query = (Profesores
        .select(Profesores, Clases)
        .join(Clases)
        .group_by(Clases.cod_curso)
        .where(Profesores.maestro_id == Clases.maestro_id))

for curso in query:
   print('El curso {} esta comienza el {} y termina el {}, y va ser impartido por {} {}'
   .format(curso.clases.cod_curso, curso.clases.fecha_inicio_curso, curso.clases.fecha_fin_curso, curso.nombre, curso.apellido))

Acá hacemos un JOIN de la tabla de “Profesores” con la tabla “Clases” y seleccionamos todos los campos de ambas tablas, utilizando un WHERE donde el maestro_id es igual en cada tabla, su sentencia SQL sería la siguiente:

SELECT "t1"."maestro_id", "t1"."nombre", "t1"."apellido", "t1"."telefono", "t1"."email", "t2"."clase_id", "t2"."cod_curso", "t2"."fecha_inicio_curso", "t2"."fecha_fin_curso", "t2"."horario", "t2"."maestro_id" FROM "profesores" AS
 "t1" INNER JOIN "clases" AS "t2" ON ("t2"."maestro_id" = "t1"."maestro_id") WHERE ("t1"."maestro_id" = "t2"."maestro_id") GROUP BY "t2"."cod_curso"

UPDATE

Para hacer un UPDATE en la tabla de “Profesores” debemos hacer lo siguiente:

chamo_update = Profesores.update(nombre='Alvaro').where(Profesores.maestro_id == 1).execute()

DELETE

En caso de querer eliminar un registro de la tabla lo hacemos de la siguiente manera:

go_delete = Clases.delete().where(Clases.cod_curso == 'go_101').execute()

Os comparto el repo git donde esta un fichero con el código de ejemplo expuesto en este post. Espero que este post os sirva como guía (aunque breve y sencilla) para utilizar este “ligero” ORM llamado PeeWee.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.