<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import os
import logging
import pyodbc
import pandas as pd
import mysql.connector
from datetime import datetime
from conexionQA import config_origen, config_destino  # Importar configuraciones de conexiÃ³n

# Asegurarse de que el directorio 'log' exista
log_dir = os.path.join(os.getcwd(), 'log')
if not os.path.exists(log_dir):
    os.makedirs(log_dir)  # Crear el directorio si no existe

# ConfiguraciÃ³n del archivo de log Ãºnico dentro de 'log/log.txt'
log_file = os.path.join(log_dir, 'log.txt')
logging.basicConfig(filename=log_file, level=logging.INFO)

def guardar_log(mensaje):
    """Guardar en el log tanto los Ã©xitos como los errores."""
    try:
        with open(log_file, 'a') as log:
            log.write(f"{datetime.now()}: {mensaje}\n")
        print(f"Se ha guardado el mensaje en {log_file}.")
    except Exception as e:
        print(f"Error al guardar el log: {str(e)}")


def obtener_datos_origen():
    """Conectar a SQL Server y obtener los datos de la tabla intencionReventa."""
    try:
        print("Realizando consulta en la base de datos de origen (SQL Server)...")
        conexion_origen = pyodbc.connect(
            f'DRIVER={config_origen["driver"]};SERVER={config_origen["server"]};PORT=1433;'
            f'DATABASE={config_origen["database"]};UID={config_origen["username"]};'
            f'PWD={config_origen["password"]};Encrypt=yes;TrustServerCertificate=yes'
        )
        print("ConexiÃ³n establecida a la base de datos de origen.")
        
        cursor = conexion_origen.cursor()

        # Consulta SQL para la tabla origen 'Campaign'
        query = """
        SELECT 
            Id,
            Number,
            Height,
            Width,
            Depth,
            Volume,
            MaxWeight
        FROM 
            Baskets;
        """
        
        print("Ejecutando consulta en la base de datos de origen...")
        cursor.execute(query)
        
        # Obtener los resultados
        filas = cursor.fetchall()
        columnas = [column[0] for column in cursor.description]
        
        # Convertir los datos en un DataFrame de pandas
        df = pd.DataFrame.from_records(filas, columns=columnas)
        
        print(f"Se obtuvieron {len(df)} filas de la base de datos de origen.")
        
        cursor.close()
        conexion_origen.close()
        
        return df
    
    except pyodbc.Error as e:
        error_message = f"Error al conectar o ejecutar consulta en la base de datos de origen: {e}"
        print(error_message)
        guardar_log(error_message)
        return None

def insertar_datos_destino(df, tabla_destino, batch_size=250):
    """Insertar los datos obtenidos en la tabla de destino en MySQL por lotes despuÃ©s de truncar la tabla."""
    try:
        print(f"Copiando datos a la base de datos destino (MySQL) en la tabla {tabla_destino}...")
        conexion_destino = mysql.connector.connect(
            host=config_destino['host'],
            user=config_destino['user'],
            password=config_destino['password'],
            database=config_destino['database'],
            port=config_destino['port'],
            charset='utf8mb4',
            collation='utf8mb4_general_ci'
        )
        
        cursor = conexion_destino.cursor()

        # Primero, realizar el truncate de la tabla
        print(f"Truncando la tabla destino {tabla_destino}...")
        cursor.execute(f"TRUNCATE TABLE {tabla_destino}")
        conexion_destino.commit()
        print(f"Tabla {tabla_destino} truncada exitosamente.")

        # Consulta INSERT para MySQL excluyendo el campo 'Id'
        insert_query = f"""
            INSERT INTO {tabla_destino} (
                id,
                number, 
                height, 
                width, 
                depth, 
                volume, 
                max_weight
            ) VALUES (%s, %s, %s, %s, %s, %s, %s)
      """
                    

        # Reemplazar valores NaN/NaT con None
        df = df.replace({pd.NA: None, 'nan': None, float('nan'): None, pd.NaT: None})
        
        valores = df.values.tolist()  # Convertir DataFrame a lista de listas
        total_filas = len(valores)
        total_lotes = (total_filas + batch_size - 1) // batch_size  # Calcular nÃºmero total de lotes

        print(f"Insertando {total_filas} registros en {total_lotes} lotes de {batch_size}...")

        for i in range(0, total_filas, batch_size):
            lote = valores[i:i + batch_size]
            cursor.executemany(insert_query, lote)
            conexion_destino.commit()
            print(f"Lote {i // batch_size + 1} de {total_lotes}: Insertados {len(lote)} registros.")
        
        cursor.close()
        conexion_destino.close()
        
        exito_message = f"Copia exitosa de la tabla {tabla_destino}. Se insertaron {total_filas} registros."
        print("Proceso finalizado con Ã©xito.")
        guardar_log(exito_message)

    except mysql.connector.Error as e:
        error_message = f"Error al insertar datos en la tabla {tabla_destino}: {e}"
        print(error_message)
        guardar_log(error_message)

def ejecutar_pasaje_con_log():
    """FunciÃ³n principal que realiza el pasaje de datos y maneja errores."""
    try:
        # Llamar a la funciÃ³n que realiza el pasaje de datos
        datos_origen = obtener_datos_origen()
        
        if datos_origen is not None and not datos_origen.empty:
            # Nombre de la tabla de destino
            tabla_destino = 'app_baskets'  # Nombre de la tabla destino

            # Insertar los datos en la base de datos destino
            insertar_datos_destino(datos_origen, tabla_destino)
            return True  # Retorna True si el pasaje fue exitoso
        
        else:
            mensaje_error = "No se encontraron datos para transferir."
            guardar_log(mensaje_error)
            print(mensaje_error)
            return False  # Retorna False si no se encontraron datos para pasar

    except Exception as e:
        # Si ocurre algÃºn error, se guarda en el archivo de log
        error_message = f"Error durante el pasaje de datos: {e}"
        print(error_message)
        guardar_log(error_message)
        return False  # Retorna False si ocurre algÃºn error

# Ejecutar el proceso de pasaje de datos con manejo de errores
resultado = ejecutar_pasaje_con_log()

if resultado:
    print("Proceso exitoso, retornando True.")
else:
    print("Proceso fallido, revisa el log de errores, retornando False.")


</pre></body></html>