python

Python – Conexión MySQL con Peewee (ORM)

En este post de programación en Python con MySQL/MariaDB te mostraré un ejemplo completo con Peewee.

Peewee es un ORM para Python que sirve para trabajar con bases de datos sin hacer consultas manuales y ayuda a reducir bastante tiempo a través de los modelos. Además, Peewee no solo se puede conectar a MariaDB, también ofrece soporte para otros motores.

A lo largo de este artículo te enseñaré un CRUD (create, read, update y delete) completo de Python con Peewe a través de un ejemplo sencillo que gestionará un diccionario con palabras y significados.

Instalando dependencias

Para instalar el ORM de Python necesitamos contar obviamente con el intérprete de Python y PIP. Para instalarlo, ejecutamos:

pip install peewee

De igual forma vamos a necesitar instalar PyMySQL ya que si bien usaremos el ORM, internamente se usará una conexión nativa:

pip install pymysql

Con eso ya podemos comenzar a trabajar y programar.

Modelo base

Peewee (como todo ORM) trabaja con modelos. Básicamente un modelo representa una tabla en la base de datos, pero específicamente con este ORM necesitamos indicar cuál conexión de base de datos se usará, además de que se debe extender de la clase Model.

Por lo tanto podemos crear una clase que extienda de Model, definir la base de datos que usarán todos los modelos y luego extender los modelos desde nuestro modelo base.

Es muy simple, con el siguiente código declaramos la conexión y nuestro modelo base para trabajar con Peewee en Python:

"""
    Antes de todo, crear una base de datos llamada "diccionario" en MySQL y 
    saber usuario con contraseña. Luego, configurar aquí
"""
from peewee import MySQLDatabase, Model, TextField
NOMBRE_BASE_DE_DATOS = "diccionario"
USUARIO = "root"
PALABRA_SECRETA = ""
conexion = MySQLDatabase(NOMBRE_BASE_DE_DATOS,
                         user=USUARIO, password=PALABRA_SECRETA)


class ModeloBase(Model):
    class Meta:
        database = conexion

Ahora podemos crear varios modelos extendiendo del modelo base, y todos van a usar la misma conexión.

Recuerda que debes configurar el usuario, nombre de la base de datos y contraseña para conectar a MySQL.

Modelo y creación de tablas

Como bien dije anteriormente, para este ejemplo vamos a gestionar un diccionario que tendrá una palabra y su significado. Entonces el modelo queda así:

class Palabra(ModeloBase):
    palabra = TextField()
    significado = TextField()

Como puedes ver tenemos dos campos, la palabra y el significado. Ambos son tipos de datos de texto así que ambos son TextField.

Para crear las tablas invocamos a create_tables de la conexión obtenida ya a través de Peewee. En este caso envío solo la clase de un modelo dentro de la lista, pero si hubiera más, se agregarían todas.

def crear_tablas():
    conexion.connect()
    conexion.create_tables([Palabra])

Operaciones en la base de datos

Es momento de ver las operaciones para insertar, eliminar, actualizar y obtener. Hay varias formas de hacerlo, yo prefiero la que te enseñaré a continuación:

def agregar_palabra(palabra, significado):
    Palabra.create(palabra=palabra, significado=significado)


Para crear un nuevo dato invocamos al método create del modelo, indicando el nombre del valor y el valor en sí. En cambio un update se ve así:

def editar_palabra(palabra, nuevo_significado):
    Palabra.update({Palabra.significado: nuevo_significado}).where(
        Palabra.palabra == palabra).execute()

Cuando invocamos a update indicamos los campos que se cambian. Como solo cambiamos el significado (que ahora será lo que tenga nuevo_significado) indicamos únicamente un campo.

Más tarde limitamos el update con where para que solo se actualice donde la palabra sea igual a la indicada. Finalmente invocamos a execute para ejecutar la actualización.

En el caso de eliminar hacemos lo siguiente:

def eliminar_palabra(palabra):
    Palabra.delete().where(Palabra.palabra == palabra).execute()

Invocamos al método delete e igualmente limitamos con where. Si queremos obtener uno o varios datos (lo que vendría a ser el SELECT) invocamos a select o a get.

def obtener_palabras():
    return Palabra.select()


def buscar_significado_palabra(palabra):
    # peewee va a lanzar una excepción si no encuentra filas que coincidan
    try:
        return Palabra.select().where(Palabra.palabra == palabra).get().significado
    except Exception:
        # Y nosotros atrapamos esa excepción devolviendo None, lo que significa que no existe la palabra
        return None

Es decir, para seleccionar todos los registros invocamos a select. Y para limitar la búsqueda invocamos a where para más tarde invocar a get (mismo que devolverá solo una fila).

Como dicen los comentarios, si no se encuentra esa fila, Peewee lanzará una excepción. Tú puedes manejarla de la manera que prefieras.

Poniendo todo junto

Ejemplo completo de Python, Peewee y MySQL MariaDB

En la imagen puedes ver el código, la ejecución del programa y la tabla de la base de datos con los datos que igualmente estamos mostrando en el software creado por Python.

Ahora solo resta invocar esos métodos desde un menú que bien puede ser el siguiente:

def principal():
    crear_tablas()
    menu = """
a) Agregar nueva palabra
b) Editar palabra existente
c) Eliminar palabra existente
d) Ver listado de palabras
e) Buscar significado de palabra
f) Salir
Elige: """
    eleccion = ""
    while eleccion != "f":
        eleccion = input(menu)
        if eleccion == "a":
            palabra = input("Ingresa la palabra: ")
            # Comprobar si no existe
            posible_significado = buscar_significado_palabra(palabra)
            if posible_significado:
                print(f"La palabra '{palabra}' ya existe")
            else:
                significado = input("Ingresa el significado: ")
                agregar_palabra(palabra, significado)
                print("Palabra agregada")
        if eleccion == "b":
            palabra = input("Ingresa la palabra que quieres editar: ")
            nuevo_significado = input("Ingresa el nuevo significado: ")
            editar_palabra(palabra, nuevo_significado)
            print("Palabra actualizada")
        if eleccion == "c":
            palabra = input("Ingresa la palabra a eliminar: ")
            eliminar_palabra(palabra)
        if eleccion == "d":
            palabras = obtener_palabras()
            print("=== Lista de palabras ===")
            for palabra in palabras:
                # Al leer desde la base de datos se devuelven los datos como arreglo, por
                # lo que hay que imprimir el primer elemento
                print(palabra.palabra)
        if eleccion == "e":
            palabra = input(
                "Ingresa la palabra de la cual quieres saber el significado: ")
            significado = buscar_significado_palabra(palabra)
            if significado:
                print(
                    f"El significado de '{palabra}' es:\n{significado}")
            else:
                print(f"Palabra '{palabra}' no encontrada")

Lo que se está haciendo es mostrar un menú, leer la acción del usuario y actuar dependiendo de la misma. De este modo el usuario puede manejar el diccionario de este ejemplo con Python y el ORM de Python.

El código completo queda así:

"""
    https://parzibyte.me/blog

    Antes de todo, crear una base de datos llamada "diccionario" en MySQL y 
    saber usuario con contraseña. Luego, configurar aquí
"""
from peewee import MySQLDatabase, Model, TextField
NOMBRE_BASE_DE_DATOS = "diccionario"
USUARIO = "root"
PALABRA_SECRETA = ""
conexion = MySQLDatabase(NOMBRE_BASE_DE_DATOS,
                         user=USUARIO, password=PALABRA_SECRETA)


class ModeloBase(Model):
    class Meta:
        database = conexion


class Palabra(ModeloBase):
    palabra = TextField()
    significado = TextField()


def crear_tablas():
    conexion.connect()
    conexion.create_tables([Palabra])


def principal():
    crear_tablas()
    menu = """
a) Agregar nueva palabra
b) Editar palabra existente
c) Eliminar palabra existente
d) Ver listado de palabras
e) Buscar significado de palabra
f) Salir
Elige: """
    eleccion = ""
    while eleccion != "f":
        eleccion = input(menu)
        if eleccion == "a":
            palabra = input("Ingresa la palabra: ")
            # Comprobar si no existe
            posible_significado = buscar_significado_palabra(palabra)
            if posible_significado:
                print(f"La palabra '{palabra}' ya existe")
            else:
                significado = input("Ingresa el significado: ")
                agregar_palabra(palabra, significado)
                print("Palabra agregada")
        if eleccion == "b":
            palabra = input("Ingresa la palabra que quieres editar: ")
            nuevo_significado = input("Ingresa el nuevo significado: ")
            editar_palabra(palabra, nuevo_significado)
            print("Palabra actualizada")
        if eleccion == "c":
            palabra = input("Ingresa la palabra a eliminar: ")
            eliminar_palabra(palabra)
        if eleccion == "d":
            palabras = obtener_palabras()
            print("=== Lista de palabras ===")
            for palabra in palabras:
                # Al leer desde la base de datos se devuelven los datos como arreglo, por
                # lo que hay que imprimir el primer elemento
                print(palabra.palabra)
        if eleccion == "e":
            palabra = input(
                "Ingresa la palabra de la cual quieres saber el significado: ")
            significado = buscar_significado_palabra(palabra)
            if significado:
                print(
                    f"El significado de '{palabra}' es:\n{significado}")
            else:
                print(f"Palabra '{palabra}' no encontrada")


def agregar_palabra(palabra, significado):
    Palabra.create(palabra=palabra, significado=significado)


def editar_palabra(palabra, nuevo_significado):
    Palabra.update({Palabra.significado: nuevo_significado}).where(
        Palabra.palabra == palabra).execute()


def eliminar_palabra(palabra):
    Palabra.delete().where(Palabra.palabra == palabra).execute()


def obtener_palabras():
    return Palabra.select()


def buscar_significado_palabra(palabra):
    # peewee va a lanzar una excepción si no encuentra filas que coincidan
    try:
        return Palabra.select().where(Palabra.palabra == palabra).get().significado
    except Exception:
        # Y nosotros atrapamos esa excepción devolviendo None, lo que significa que no existe la palabra
        return None


if __name__ == '__main__':
    principal()

Basta con ejecutar el script y usar el menú. Así es como podemos hacer una aplicación conectando Python con MySQL sin escribir consultas manualmente, pues todo se hace a través del ORM Peewee.

Recuerda que este código es gratuito y open source así que puedes usarlo como tú prefieras; modificarlo, mejorarlo, etcétera.

Para terminar el post te dejo con más tutoriales de Python y MariaDB.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

6 días hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

6 días hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

6 días hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

6 días hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

6 días hace

Solución: Apache – Server unable to read htaccess file

Ayer estaba editando unos archivos que son servidos con el servidor Apache y al visitarlos…

7 días hace

Esta web usa cookies.