En esta ocasión, voy a mostraros como implantar un método para obtener las tablas de una base de datos MySQL desde Python y otro para obtener las columnas de dichas tablas.
Método para obtener tablas MySQL desde Python
Empecemos con un método que sea capaz de consultar las tablas que hay en una base de datos.
Para esto, necesitamos lanzar dos instrucciones SQL, una que seleccione la base de datos en el servidor y otra para ejecutar la instrucción que sirve para mostrar las tablas.
Instrucciones MySQL para mostrar todas las tablas de una base de datos
La primera es la de «usar» una base de datos en concreto:
USE nombre_base_datos;
La siguiente es la de mostrar tablas en esa base de datos:
SHOW TABLES;
Método para consultar tablas MySQL desde Python
Con estos datos, ya podemos crear fácilmente una instrucción para consultar las tablas en cualquier base de datos desde un método Python.
En la llamada, se necesitará un argumento para el nombre de la base de datos que queremos utilizar. Por lo tanto, la llamada, quedará así:
base_datos.mostrar_tablas("nombre_bd")
Tenemos que tener en cuenta, que estaría bien, que se comprobara si existe o no la base de datos proporcionada, de esa forma, nos avisará si no existe.
Aquí tienes el método.
Primero, se verifica si existe la base de datos pasada como argumento. Si no existe, se finaliza la ejecución con el if. La explicación es la misma que di anteriormente con el método de copias de seguridad.
Esta parte del código, se podría establecer en otro método decorador más, ya que es algo que se puede usar en más de un caso. Sin embargo, para no estar repitiendo tanto lo mismo, lo dejo en tus manos, para que practiques un poco más.
El cursor, si la base de datos existe, lanza la instrucción SQL necesaria para seleccionar la base de datos con la cual queremos consultar las tablas.
Las tablas se iteran y muestran de la misma forma que hicimos con «SHOW DATABASES» en el método mostrar_db().
# Método para mostrar las tablas de una base de datos @conexion def mostrar_tablas(self, nombre_bd): # Primero, se verifica si la base de datos existe sql = f"SHOW DATABASES LIKE '{nombre_bd}'" self.cursor.execute(sql) resultado = self.cursor.fetchone() # Si la base de datos no existe, muestra un mensaje de error y termina la función if not resultado: print(f'La base de datos {nombre_bd} no existe.') return # Se selecciona la base de datos self.cursor.execute(f"USE {nombre_bd};") # Se informa de que se están obteniendo las tablas print("Aquí tienes el listado de las tablas de la base de datos:") # Realiza la consulta para mostrar las tablas de la base de datos actual self.cursor.execute("SHOW TABLES") resultado = self.cursor.fetchall() # Recorre los resultados y los muestra por pantalla for tabla in resultado: print(f"-{tabla[0]}.")
Si la base de datos existe, esta es la salida:
base_datos.mostrar_tablas("world")
Resultado en la consola
Se abrió la conexión con el servidor.
Aquí tienes el listado de las tablas de la base de datos:
-city.
-country.
-countrylanguage.
Se cerró la conexión con el servidor.
En cambio, si no existe…
base_datos.mostrar_tablas("base_datos_inexistente")
Resultado en la consola
Se abrió la conexión con el servidor.
La base de datos base_datos_inexistente no existe.
Se cerró la conexión con el servidor.
Método para consultar columnas de tablas MySQL desde Python
Seguimos con más métodos. Ahora, hagamos uno que nos muestre los campos que tiene una tabla con su longitud y tipo de dato, si es clave primaria…
En MySQL, la instrucción para mostrar las columnas de una tabla, es esta:
USE nombre_bd; SHOW COLUMNS FROM nombre_tabla;
Para este cometido, necesitaremos que en la llamada se proporcione un nombre de la base de datos y un nombre de tabla.
Comprobamos lo mismo que en la función anterior, si existe la base de datos. En el caso de que así sea, se selecciona la base de datos.
Después, se intenta realizar la acción de mostrar las tablas.
El execute() y el fetchall de las líneas 17 y 18, nos dan una lista como esta:
Resultado en la consola
[(‘ID’, ‘int’, ‘NO’, ‘PRI’, None, ‘auto_increment’), (‘Name’, ‘char(35)’, ‘NO’, », », »), (‘CountryCode’, ‘char(3)’, ‘NO’, ‘MUL’, », »), (‘District’, ‘char(20)’, ‘NO’, », », »), (‘Population’, ‘int’, ‘NO’, », ‘0’, »)]
Esta lista, contiene una tupla por posición en el índice. Cada tupla, tiene toda la información sobre las columnas en diferentes posiciones. Esta vez, queremos solo los campos de nombres, pues en este caso, se itera en el bucle for, la posición 0 de cada tupla.
@conexion def mostrar_columnas(self, nombre_bd, nombre_tabla): # Primero, se verifica si la base de datos existe sql = f"SHOW DATABASES LIKE '{nombre_bd}'" self.cursor.execute(sql) resultado = self.cursor.fetchone() # Si la base de datos no existe, muestra un mensaje de error y termina la función if not resultado: print(f'La base de datos {nombre_bd} no existe.') return # Establece la base de datos actual self.cursor.execute(f"USE {nombre_bd}") try: # Realiza la consulta para mostrar las columnas de la tabla especificada self.cursor.execute(f"SHOW COLUMNS FROM {nombre_tabla}") resultado = self.cursor.fetchall() # Se informa de que se están obteniendo las columnas print(f"Aquí tienes el listado de las columnas de la tabla '{nombre_tabla}':") # Recorre los resultados y los muestra por pantalla for columna in resultado: print(f"-{columna[0]}.") except: print("Ocurrió un error. Comprueba el nombre de la tabla.")
Probemos una llamada a una base de datos existente y con tabla también existente.
base_datos.mostrar_columnas("world", "city")
Resultado en la consola
Se abrió la conexión con el servidor.
Aquí tienes el listado de las columnas de la tabla ‘city’:
-ID.
-Name.
-CountryCode.
-District.
-Population.
Se cerró la conexión con el servidor.
Ahora, probemos una tabla inexistente y una base de datos existente.
base_datos.mostrar_columnas("world", "tabla_inexistente")
Resultado en la consola
Se abrió la conexión con el servidor.
Ocurrió un error. Comprueba el nombre de la tabla.
Se cerró la conexión con el servidor.
Si no existen ninguna de las dos…
base_datos.mostrar_columnas("base_datos_inexistente", "tabla_inexistente")
Resultado en la consola
Se abrió la conexión con el servidor.
La base de datos base_datos_inexistente no existe.
Se cerró la conexión con el servidor.
Te dejo, como ejercicio, que intentes mostrar en la salida de las columnas lo siguiente:
- Nombre de la columna.
- Tipo de dato y longitud.
- También si es clave primaria o clave foránea.
- Si admite valores nulos.
Por lo de clave primaria, aparecerá como ‘PRI’ y la clave foránea o externa (foreign key) como ‘MUL’.
Si no admite valores nulos, aparecerá un ‘NO’.
Pues entonces, quiero que saques un reporte como este (esto es de la tabla city, de la base de datos world, pero debe funcionar con cualquier tabla):
- -ID int. No admite valores nulos. Es clave primaria.
- -Name char(35) No admite valores nulos.
- -CountryCode char(3) No admite valores nulos. Es clave externa.
- -District char(20) No admite valores nulos.
- -Population int No admite valores nulos.
También, si te fijas, en todos los métodos que tenemos que pasar un nombre de base de datos, podríamos incluir esta comprobación:
# Verifica si la base de datos existe en el servidor sql = f"SHOW DATABASES LIKE '{nombre_bd}'" self.cursor.execute(sql) resultado = self.cursor.fetchone() # Si la base de datos no existe, muestra un mensaje de error y termina la función if not resultado: print(f'La base de datos {nombre_bd} no existe.') return
¿Qué tal si intentas crear un método decorador para no estar repitiendo esto?
No te pierdas nada del curso Máster en Python.
Mi propuesta para la solución del ejercicio usando match (switch):
@conexion
def mostrar_tablas(self,nombre_bd):
# Verifica si la base de datos existe en el servidor
sql = f»SHOW DATABASES LIKE ‘{nombre_bd}'»
self.cursor.execute(sql)
resultado = self.cursor.fetchone()
# Si la base de datos no existe, muestra un mensaje de error y termina el método
if not resultado:
print(f’La base de datos {nombre_bd} no existe.’)
return
#Se selecciona la bd
self.cursor.execute(f»USE {nombre_bd};»)
#Se informa de que se están obteniendo las tablas
print(f»Aquí tienes un listado de las tablas de la base de datos {nombre_bd}:»)
#Realiza la consulta para mostrar las tablas de la bd.
self.cursor.execute(f»SHOW TABLES;»)
resultado = self.cursor.fetchall()
#Recorre los resultados y los muestra por pantalla
for tabla in resultado:
print(f»-{tabla[0]}»)
#Mostrar columnas de una tabla
@conexion
def mostrar_columnas(self,nombre_bd,nombre_tabla):
# Verifica si la base de datos existe en el servidor
sql = f»SHOW DATABASES LIKE ‘{nombre_bd}'»
self.cursor.execute(sql)
resultado = self.cursor.fetchone()
# Si la base de datos no existe, muestra un mensaje de error y termina el método
if not resultado:
print(f’La base de datos {nombre_bd} no existe.’)
return
#Se selecciona la bd
self.cursor.execute(f»USE {nombre_bd};»)
try:
#Realiza la consulta para mostrar todas las columnas de la tabla seleccionada
self.cursor.execute(f»SHOW COLUMNS FROM {nombre_tabla};»)
resultado = self.cursor.fetchall()
#Recorre los resultados y los muestra por pantalla
print(f»Aquí tienes el listado de las columnas de la tabla:»)
for columna in resultado:
match columna[2]:
case ‘NO’:
null = «No admite valores nulos.»
case ‘YES’:
null = «Sí admite valores nulos.»
case _:
null = »
match columna[3]:
case ‘PRI’:
clave = «Es clave primaria.»
case ‘MUL’:
clave = «Es clave externa.»
case _:
clave = »
print(f»-{columna[0].capitalize()} {columna[1]} {null} {clave}»)
except:
print(f»Ocurrió un error con el nombre de la tabla»)