¿Cómo crear aplicaciones con Python – MySQL y Tkinter?

¿Cómo crear aplicaciones con Python – MySQL y Tkinter?

¿Cómo crear aplicaciones con Python - MySQL y Tkinter? - Parte 2 - Máster en Python #27

Seguimos con el proyecto que empecé en el capítulo 26. Un proyecto para aprender a crear aplicaciones que utilicen Python, MySQL y Tkinter.

Hasta este punto, ya tenemos una clase que posee conexión a cualquier servidor MySQL solo pasándole un diccionario con los datos.

Esta clase posee, aparte de la conexión, dos métodos listos para trabajar directamente con bases de datos MySQL.

Dejamos el proyecto así en el capítulo anterior:

Archivos del proyecto

archivo paquete Python __init__.py

Código app.py

import bd.base_datos as sqlbd

base_datos = sqlbd.BaseDatos(**sqlbd.acceso_bd)

base_datos.mostrar_bd()

Código base_datos.py

Por cierto, en "acceso_bd" he eliminado la clave "database", ya que de momento, para las pruebas de estos capítulos no nos sirve.

import mysql.connector

#conexion con la base de datos
acceso_bd = {"host" : "localhost",
             "user" : "root",
             "password" : "programacionfacil",
             }

class BaseDatos:
    def __init__(self, **kwargs):
        self.conector = mysql.connector.connect(**kwargs)
        
    def consulta(self, sql):
        self.cursor = self.conector.cursor()
        self.cursor.execute(sql)
        return self.cursor
    
    def mostrar_bd(self):
        self.cursor.execute("SHOW DATABASES")
        for bd in self.cursor:
            print(bd)

Nos quedamos con el siguiente error, el cual, te dije que trataras de resolver. Si lo conseguiste, enhorabuena, si no, a continuación, tienes la solución para que sigas aprendiendo.

Error en la consola

AttributeError: 'BaseDatos' object has no attribute 'cursor'

El error es porque no tenemos alcance para utilizar el atributo "cursor" de un método a otro.

Una posible solución, hubiera sido crear un cursor para cada método, pero ¿y si tenemos 50 métodos en la clase? ¿Creamos 50 cursores?

Esta es una solución, pero no muy buena. Lo mejor, es que el cursor se cree en el método __init__. Eso le da acceso a los atributos en todos los métodos empleados por los objetos.

base_datos.py

La clase quedará así. Tenemos en el __init__ la conexión y la creación del cursor. Esto ya nos da acceso a estos dos elementos en toda la clase, por todos sus métodos.

class BaseDatos:
    #Conexión y cursor
    def __init__(self, **kwargs):
        self.conector = mysql.connector.connect(**kwargs)
        self.cursor = self.conector.cursor()
    
    #Consultas SQL    
    def consulta(self, sql):
        self.cursor.execute(sql)
        return self.cursor
    
    #Mostrar bases de datos
    def mostrar_bd(self):
        self.cursor.execute("SHOW DATABASES")
        for bd in self.cursor:
            print(bd)

app.py

Ahora sí, con apenas 3 líneas de código, estamos creando una conexión con un servidor MySQL, estamos creando un cursor, pasándole una instrucción SQL y presentándola en la consola con un bucle.

import bd.base_datos as sqlbd

base_datos = sqlbd.BaseDatos(**sqlbd.acceso_bd)

base_datos.mostrar_bd()

Este es uno de los ejemplos de lo maravillosa y poderosa que es la programación orientada a objetos.

No te vayas, porque queda mucho más que ver.

Método para eliminar bases de datos desde Python

¿No sería genial que nuestra clase tuviera también un método que pudiera eliminar bases de datos con solo utilizar su nombre?

Vamos a dejar de imaginarlo y hagámoslo realidad.

Ves a la clase que estamos construyendo y debajo del último método, añade este:

#Eliminar bases de datos
    def eliminar_bd(self, nombre_bd):
        try:
            self.cursor.execute(f"DROP DATABASE {nombre_bd}")
            print(f"Se eliminó la base de datos {nombre_bd} correctamente.")
        except:
            print(f"Base de datos '{nombre_bd}' no encontrada.")

Este método esperará un parámetro. El nombre de la base de datos.

Mediante ese nombre, probará con un try de ejecutar el comando correspondiente para eliminar una base de datos. Gracias al formateo de strings, le paso directamente a la instrucción SQL el nombre de la base de datos.

Si la eliminación fue satisfactoria, dirá que la base de datos se eliminó correctamente. En caso contrario, pasamos al bloque except.

Aquí nos dirá que la base de datos no se ha encontrado.

En el archivo app.py, voy a eliminar la base de datos llamada "american_rider".

base_datos.eliminar_bd("american_rider")

Resultado en la consola

Se eliminó la base de datos american_rider correctamente.

Se ha eliminado correctamente.

Ahora, vayamos a intentar de eliminar una base de datos inexistente. Así probamos el bloque except.

base_datos.eliminar_bd("base_datos_cualquiera.")

Resultado en la consola

Base de datos 'base_datos_cualquiera' no encontrada.

Pero claro, ahora, la persona que estuviera programando, debería saber que bases de datos tiene el servidor, así verá en qué se ha equivocado al poner el nombre de la base de datos.

En este caso, llamaría al método de consulta de bases de datos:

base_datos.mostrar_bd()

Vería el listado y así, podría saber si tiene que proceder a intentar la eliminación nuevamente.

Es aquí, donde se me ocurre, aprovechar código para evitarle que tenga que utilizar dos métodos. Le voy a añadir la llamada al método mostrar_bd() solo si se equivoca en el nombre.

    #Eliminar bases de datos
    def eliminar_bd(self, nombre_bd):
        try:
            self.cursor.execute(f"DROP DATABASE {nombre_bd}")
            print(f"Se eliminó la base de datos {nombre_bd} correctamente.")
        except:
            print(f"Base de datos '{nombre_bd}' no encontrada.")
            print("Estas son las bases de datos que tiene el servidor:")
            self.mostrar_bd()

Esta vez, después de decirle que no se ha encontrado, nos va a hacer una llamada automáticamente, al método mostrar_bd(), con el fin de que le aparezca el listado.

base_datos.eliminar_bd("base_datos_cualquiera.")

Resultado en la consola

Base de datos 'base_datos_cualquiera.' no encontrada.
Estas son las bases de datos que tiene el servidor:
('information_schema',)
('mysql',)
('performance_schema',)
('pruebas',)
('sakila',)
('sys',)
('world',)

Te dejo como reto para el siguiente capítulo, que intentes hacer un método similar a este, pero que en lugar de eliminar bases de datos, las cree. La solución te la daré en el próximo capítulo.

No te pierdas nada de todo el contenido que tengo sobre Python.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

curso Java Entrada anterior Introducción a la programación orientada a objetos con Java
curso Java Entrada siguiente Crear clases y crear objetos en Java