En este capítulo, te voy a mostrar como crear un método para eliminar tablas MySQL desde Python. También, otro para eliminarlas.
Método para crear tablas MySQL desde Python
En esta ocasión, vamos a crear un método que pueda crear tablas en la base de datos.
Por el momento, así llevamos el proyecto de bases de datos:
import mysql.connector import os import subprocess import datetime #conexion con la base de datos acceso_bd = {"host" : "localhost", "user" : "root", "password" : "programacionfacil", } # --> Rutas #Obtenemos la raíz de la carpeta del proyecto carpeta_principal = os.path.dirname(__file__) carpeta_respaldo = os.path.join(carpeta_principal, "respaldo") class BaseDatos: #Conexión y cursor def __init__(self, **kwargs): self.conector = mysql.connector.connect(**kwargs) self.cursor = self.conector.cursor() self.contrasena = kwargs["password"] #Decoradora para el reporte de bases de datos en el servidor def reporte_bd(funcion_parametro): def interno(self, nombre_db): funcion_parametro(self, nombre_db) print("Estas son las bases de datos que tiene el servidor:") BaseDatos.mostrar_bd(self) return interno #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) #Eliminar bases de datos @reporte_bd 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.") #Crear bases de datos @reporte_bd def crear_bd(self, nombre_bd): try: self.cursor.execute(f"CREATE DATABASE IF NOT EXISTS {nombre_bd}") print(f"Se creó la base de datos {nombre_bd} o ya estaba creada.") except: print(f"Ocurrió un error al intentar crear la base de datos {nombre_bd}.") #Crear backups de bases de datos def copiar_bd(self, nombre_bd): #Obtiene la hora y fecha actuales self.fecha_hora = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S") #Se crea la copia de seguridad with open(f'{carpeta_respaldo}/{nombre_bd}_{self.fecha_hora}.sql', 'w') as out: subprocess.Popen(f'"C:/Program Files/MySQL/MySQL Workbench 8.0/"mysqldump --user=root -- password={self.contrasena} --databases {nombre_bd}', shell=True, stdout=out)
Para crear tablas en SQL, necesitamos varias cosas.
- Nombre de la base de datos en la que queremos crear la tabla.
- Nombre de la tabla.
- Nombres de las columnas que forman la tabla.
- Tipos de datos en las columnas.
- Longitudes de las columnas.
- Saber si la columna es clave primaria o no.
- Saber si será una columna autoincrementable o no.
- Saber su una columna admite o no valores nulos.
Entonces, esto nos plantea un reto mucho mayor que lo que hemos hecho hasta ahora. Tenemos que crear un método que con una simple llamada de todos estos datos y además, haga efectiva la creación de la tabla en el servidor.
Hay muchas formas de hacer esto. Espero que la que yo he elegido, sea la más fácil de entender. La he intentado simplificar mucho para que no haya mucho código.
Declaración del método para crear tablas MySQL desde Python
Primero, te dejo todo el código del método y después te lo explico en partes.
def crear_tabla(self, nombre_bd, nombre_tabla, columnas): #String para guardar el string con las columnas y tipos de datos columnas_string = "" #Se itera la lista que se le pasa como argumento (cada diccionario) for columna in columnas: #formamos el string con nombre, tipo y longitud columnas_string += f"{columna['name']} {columna['type']}({columna['length']})" #Si es clave primaria, auto_increment o no adminte valores nulos, lo añade al string if columna['primary_key']: columnas_string += " PRIMARY KEY" if columna['auto_increment']: columnas_string += " AUTO_INCREMENT" if columna['not_null']: columnas_string += " NOT NULL" #Hace un salto de línea después de cada diccionario columnas_string += ",\n" #Elimina al final del string el salto de línea y la coma columnas_string = columnas_string[:-2] #Le indica que base de datos utilizar self.cursor.execute(f"USE {nombre_bd}") #Se crea la tabla juntando la instrucción SQL con el string generado sql = f"CREATE TABLE {nombre_tabla} ({columnas_string});" #Se ejecuta la instrucción self.cursor.execute(sql) #Se hace efectiva self.conector.commit() #Se cierra la conexión con el servidor self.conector.close()
Vayamos a la clase «BaseDatos». Abajo del todo, empezaremos con la declaración del método.
def crear_tabla(self, nombre_bd, nombre_tabla, columnas):
Este método funcionará pasándole diccionarios al parámetro «columnas». Aquí tienes un ejemplo:
columnas = [ { 'name': 'id', 'type': 'INT', 'length': 10, 'primary_key': True, 'auto_increment': True, 'not_null': True }, { 'name': 'nombre', 'type': 'VARCHAR', 'length': 32, 'primary_key': False, 'auto_increment': False, 'not_null': True }, { 'name': 'apellidos', 'type': 'VARCHAR', 'length': 64, 'primary_key': False, 'auto_increment': False, 'not_null': True }, { 'name': 'telefono', 'type': 'VARCHAR', 'length': 9, 'primary_key': False, 'auto_increment': False, 'not_null': False }, { 'name': 'direccion', 'type': 'VARCHAR', 'length': 128, 'primary_key': False, 'auto_increment': False, 'not_null': False } ] base_datos.crear_tabla('base_datos_cualquiera', 'nombre_tabla', columnas)
En los parámetros, necesitaremos pasar el nombre de la base de datos, el nombre de la nueva tabla y cada una de las columnas, estas se pasarán con listas con varios diccionarios como este. Cada columna tiene su propio diccionario con las claves y valores que lo definen.
Creamos un string vacío. Aquí iré agregando todos los datos de columnas, tipos y longitudes que formarán finalmente la instrucción SQL («CREATE TABLE …»).
columnas_string = ""
Un bucle for, que va a iterar y formar el string mediantes lo que le pasemos en el parámetro «columnas».
for columna in columnas: #formamos el string con nombre, tipo y longitud columnas_string += f"{columna['name']} {columna['type']}({columna['length']})" #Si es clave primaria o auto_increment, lo añade al string if columna['primary_key']: columnas_string += " PRIMARY KEY" if columna['auto_increment']: columnas_string += " AUTO_INCREMENT" if columna['not_null']: columnas_string += " NOT NULL"
Finalmente, nos queda este string slicing que borra las dos últimas posiciones de «columnas string» ¿Por qué? Bien, esto es debido a que el string, se está formando así, con comas y saltos de línea.
id INT (10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
nombre NOT NULL VARCHAR (32),
apellidos NOT NULL VARCHAR (64),
telefono VARCHAR (9),
direccion VARCHAR (128),
Entonces, si en la instrucción SQL dejamos ese salto de línea y la coma del final, nos dará error. Por lo tanto, una solución, es reasignar el valor de «columnas_string» con su propio substring menos las últimas dos posiciones de caracteres (coma y salto de línea).
Después, le paso a la declaración SQL USE el nombre de la base de datos. Aquí le indico donde crear la tabla.
En la variable «sql» formo la instrucción SQL para crear la tabla, mediante «CREATE TABLE» + el nombre de la tabla + (string con todos los campos, longitudes y demás).
Finalmente, lo que tenemos, sería esto:
CREATE TABLE clientes (id INT (10) NOT NULL AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR (32) NOT NULL, apellidos VARCHAR (64) NOT NULL, telefono VARCHAR (9) NOT NULL, direccion VARCHAR (256), PRIMARY KEY (id));
Es la instrucción exacta que le pasaríamos al servidor para crear una tabla. Se respeta toda la sintaxis SQL en el string formado por el método.
Finalmente, ejecutamos la instrucción mediante el cursor y hacemos los cambios efectivos con el «commit».
Por supuesto, hay que cerrar la conexión con el servidor al terminar de crear la tabla.
#Elimina al final del string el salto de línea y la coma columnas_string = columnas_string[:-2] #Le indica que base de datos utilizar self.cursor.execute(f"USE {nombre_bd}") #Se crea la tabla juntando la instrucción SQL con el string generado sql = f"CREATE TABLE {nombre_tabla} ({columnas_string});" #Se ejecuta la instrucción self.cursor.execute(sql) #Se confirman los cambios en la base de datos self.conector.commit() #Se cierra la conexión con el servidor self.conector.close()
Método para eliminar tablas MySQL desde Python
Lo difícil ya está hecho. El método para crear tablas es mucho más complejo que el de eliminarlas, ya que la instrucción SQL para eliminar una tabla es la siguiente:
DROP TABLE nombre_tabla;
También hay que tener en cuenta, que se debe especificar en que base de datos se va a eliminar la tabla. El método quedará con dos parámetros, el nombre de la base de datos y el nombre de la tabla.
#Eliminar tablas en las bases de datos def eliminar_tabla(self, nombre_bd, nombre_tabla): self.cursor.execute(f"USE {nombre_bd}") self.cursor.execute(f"DROP TABLE {nombre_tabla}")
La llamada será algo como esto:
base_datos.eliminar_tabla("nombre_base_datos", "nombre_tabla")
Dejamos el capítulo aquí. En el siguiente, pasamos a la creación de métodos para insertar registros en tablas, eliminarlos y consultarlos.
Soluciones a los ejercicios del capítulo anterior
Aquí tienes las soluciones de los ejercicios propuestos en el capítulo anterior:
- Aquí no importaba complicarse mucho, bastaba con un simple cero. Recuerda que las otras dos partes del string slicing, a veces, son opcionales, depende de lo que queramos hacer.
#Creamos la frase frase = "Estoy estudiando Python" print(frase[0]) # Imprime "E"
#Creamos la frase frase = "Estoy estudiando Python" print(frase[-3:]) # Imprime "hon"
- Este resultado es extraño. Lo puse para que dudaras sobre si lo estabas haciendo bien o mal.
#Creamos la frase frase = "Estoy estudiando Python" print(frase[::2]) # Imprime "EoetuiagPto"
- Finalmente, imprimimos todo menos el último caracter.
#Creamos la frase frase = "Estoy estudiando Python" print(frase[:-1]) # Imprime "Estoy estudiando Pytho"
Piensa que puedes haber hecho los ejercicios de manera algo diferente. Si tienes los mismos resultados en la consola que yo, es que lo has hecho bien.
Aquí tienes todo el temario del curso.
Si quiero crear más tablas, y en una tabla usuario, quiero establecer roles:
– administrador
– asistente
– auxiliar
– practicante
como debería escribirlo en el diccionario, y entiendo que se tiene que tener la misma informacion para cada columna, en las otras columnas debo poner False
pero debería aumentarle a cada columna no?
Traceback (most recent call last):
File «c:\Users\HP\OneDrive\Documents\CURSOS\Curs Python\Dies\PROJECTE-BD\app.py», line 2, in
import BD.tables as tbl
File «c:\Users\HP\OneDrive\Documents\CURSOS\Curs Python\Dies\PROJECTE-BD\BD\tables.py», line 44, in
base_dades.crear_tabla(‘base_dades_cualquiera’, ‘nombre_tabla’, columnes)
^^^^^^^^^^
NameError: name ‘base_dades’ is not defined
PS C:\Users\HP\OneDrive\Documents\CURSOS\Curs Python\Dies>
tengo el mismo error y no se la razon
Excelente información , me fue de mucha ayuda ya que no tengo tanta experiencia en el uso de bases de datos MySQL , espero que sigan compartiendo mas información sobre las bases de datos , tuve problemas para instalar MySQL , les comparto un manual paso a paso de como instalar un servidor MySQL.
Traceback (most recent call last):
File «c:\Users\esteb\Desktop\Programacion\PYTHON\master Python\PROYECTO 1\app.py», line 17, in
base_datos.crear_tabla(«prueba_de_def»,»usuarios»,tbl.columnas)
File «c:\Users\esteb\Desktop\Programacion\PYTHON\master Python\PROYECTO 1\bd\base_datos.py», line 97, in crear_tabla
self.cursor.execute(f»USE {nombre_bd}»)
File «C:\Users\esteb\AppData\Local\Programs\Python\Python311\Lib\site-packages\mysql\connector\cursor_cext.py», line 302, in execute
raise ProgrammingError(«Cursor is not connected», 2055) from err
mysql.connector.errors.ProgrammingError: 2055: Cursor is not connected
PS C:\Users\esteb\Desktop\Programacion\PYTHON\master Python\PROYECTO 1>
primero lo hice, luego lo copie de aqui al codigo por las dudas y me arroja el mismo problema.
Resuelto! el problema era que agregue por mi cuenta el cerrar conexion del cursor antes que lo explique el video abajo de todo y nunca lo elimine jaja