Copias de seguridad MySQL con hora y fecha automática con Python

curso de Python

Introducción al capítulo

Seguimos avanzando en el proyecto de bases de datos. En este capítulo, me dedicaré a resolver el reto que te propuse anteriormente, para que no se pida la contraseña del servidor MySQL para hacer la copia de seguridad y luego, te enseñaré a aplicar la hora y fecha automáticamente a las copias de seguridad MySQL creadas desde Python.

Entonces, lo primero que voy a hacer, será resolver el reto que te propuse hace un par de capítulos. El de prescindir de tener que escribir la contraseña en la consola cuando ejecutamos la copia de seguridad.

Primero, retira la importación del módulo getpass. De momento, no se va a utilizar.

En el método __init__ de la clase BaseDatos he accedido a la clave «pasword» del diccionario que se le pase. De esta forma, en el atributo «contrasena» se va a guardar la contraseña de cualquier diccionario que tenga la clave «password».

self.contrasena = kwargs["password"]

Después, en el método de crear la copia de seguridad, le cambio el valor de pasword por el que lleve «contrasena».

Ahora, al llamar al método copia_bd(), se hará la copia sin poner contraseña.

Así con todo, el archivo base_datos.py deberías tenerlo así:

import mysql.connector
import os
import subprocess

#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 copia_bd(self, nombre_bd):
        with open(f'{carpeta_respaldo}/{nombre_bd}.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)

Añadir fecha y hora a las copias MySQL hechas desde Python

Lo siguiente que haremos, será añadir la fecha y la hora actuales al nombre del archivo .sql que se genera al crear la copia de seguridad. De esta forma, podemos tener varios respaldos de la misma base de datos en diferentes ocasiones. De la forma que lo tenemos ahora, al hacer una copia de la misma base de datos, se reemplaza la anterior.

Importamos el módulo datetime para trabajar con fechas en Python.

import datetime

Nos vamos al método copia_bd y obtenemos la fecha y hora actuales. Esto lo formateamos como string con las partes que nos interesan de la fecha y en el orden que queramos.

fecha_hora = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")

print(fecha_hora)

El print() es solo para que veas la salida que da.

Resultado en la consola

2022-12-20 17:20:50

Ahora que ya tenemos el string con la fecha de cada momento en que se ejecute la llamada al método, solo hay que incrustarlo en el nombre de archivo.

    #Crear backups de bases de datos
    def copia_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)

Listo, ya tenemos copias de seguridad con el bonito detalle de la hora y la fecha, que a la hora de recuperar datos, será de gran utilidad.

Dejamos el capítulo aquí. En el siguiente, crearemos dos métodos para crear y eliminar tablas en las bases de datos. En otro capítulo mostraré también como crear métodos para añadir, eliminar y consultar registros.

Cuando acabemos con todo esto, pasaremos a crear una interfaz gráfica para todo esto con Tkinter, de forma que hagamos todo de manera gráfica.

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

Soluciones de los ejercicios del capítulo anterior

Aquí tienes el código correspondiente a cada ejercicio del capítulo anterior:

from datetime import datetime

# 1 - Muestra la hora actual en formato hh:mm:ss.
print(datetime.now().strftime('%H:%M:%S'))

# 2 - Muestra la fecha actual en formato dd/mm/yyyy.
print(datetime.now().strftime('%d/%m/%Y'))

# 3 - Crea una variable con una fecha y hora específicas (por ejemplo, 21 de diciembre de 2023 a las 13:45) y muestra solo la hora y los minutos.
fecha_hora_especifica = datetime(2023, 12, 21, 13, 45)
print(fecha_hora_especifica.strftime('%H:%M'))

# 4 - Crea una variable con una fecha y hora específicas (por ejemplo, 10 de noviembre de 2023 a las 13:45) y muestra solo el día y el mes.
fecha_hora_especifica = datetime(2023, 11, 10, 13, 45)
print(fecha_hora_especifica.strftime('%d/%m'))

# 5 - Obtén la fecha actual y formatéala para mostrar el mes en formato de tres letras (por ejemplo, «ene» para enero).
print(datetime.now().strftime('%b'))

# 6-  Obtén la fecha actual y formatéala para mostrar el día de la semana en formato de tres letras (por ejemplo, «lun» para lunes).
print(datetime.now().strftime('%a'))

# 7 - Crea una variable con una fecha y hora específicas (por ejemplo, 15 de septiembre de 2023 a las 13:45) y muestra la fecha y hora en formato «día de mes de año, hora:minutos».
fecha_hora_especifica = datetime(2023, 9, 15, 13, 45)
print(fecha_hora_especifica.strftime('%d de %m de %Y, %H:%M'))

# 8 - Obtén la fecha actual y formatéala para mostrar el mes en formato de dos dígitos (por ejemplo, «01» para enero).
print(datetime.now().strftime('%m'))
Copias de seguridad MySQL con hora y fecha automática con Python

4 comentarios en «Copias de seguridad MySQL con hora y fecha automática con Python»

  1. Buenas tardes
    Un curso genial, después de muuuchos años he vuelto a programar, lo hago por puro entretenimiento y me encanta. Muchas gracias.
    Sobre el código de copia de seguridad. Me crea el fichero en el directorio respaldo, no me sale ningún error, pero el archivo creado me sale con 0 bytes. Como base de datos le paso alguna de las que aparecen como ejemplos en la instalación de Mysql, «World», «Sakila» ¿?

  2. Hola Enrique,
    Agradezco mucho el tiempo que dedicas a este curso llevo varios meses estudiandolo. Actuamente voy por el módulo 12, tema 7, y estoy muy entusiasmado, lo explica muy bien, y esta pendiente de cada detalles, incluyendo los ejercicios para profundizar en lo aprendido. voy a mi propio ritmo ya que trabajo a tiempo completo y tengo familia, lo cual me limita en cuanto a la cantidad de tiempo. ya tengo cierto conocimiento en programacion, lo cual se me hace mas facil.

    Que Jehová te sigas bendiciendo.

    1. Hola, fíjate en el tipo de dato que estás pasando, ahí dice que se está pasando un string en lugar de un integer. Necesitaría ver el trozo de código donde te ocurre.

Deja una respuesta

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

Scroll hacia arriba