Saltar a contenido

Importación de rolado

Este script en Python permite migrar información desde una base de datos Oracle hacia una base de datos MariaDB/MySQL. Utiliza las bibliotecas cx_Oracle para conectarse a Oracle y pymysql para conectarse a MariaDB. El código incluye funciones para migrar tablas completas, ejecutar scripts SQL y realizar consultas específicas con condiciones en las tablas de origen.

Importación de librerías

El script utiliza las siguientes librerías:

  • cx_Oracle: Para conectarse a bases de datos Oracle.
  • pymysql: Para conectarse a bases de datos MariaDB o MySQL.
  • time: Utilizada para registrar el tiempo de las operaciones.
import cx_Oracle
import pymysql
import time

Conexiones a las bases de datos

  • target_db: Conexión a la base de datos MariaDB/MySQL (base de datos de destino).
  • source_db: Conexión a la base de datos Oracle (base de datos de origen).
    source_db_type = 'Oracle'
    target_db_type = 'MySQL'
    target_db = pymysql.connect(
        host='HOST',
        user='USUARIO',
        password="PASSWORD",
        db='NOMBRE_BASE_DATOS',
    )
    
    cx_Oracle.init_oracle_client(lib_dir=r"c:\instantclient_21_7")
    source_db = cx_Oracle.connect('USUARIO/CONTRASEÑA@IP_SERVIDOR/DVLP') #Cambiar el usuario, contraseña, IP o HOST y DVLP (ambiente de desarrollo) por los datos de la base de datos Oracle a la que se desea conectar.
    

Funciones del script

primerosncamposdelatabladestino(tabla, n) Esta función obtiene los primeros n campos de una tabla de destino para asegurar la estructura de la tabla.

    def primerosncamposdelatabladestino(tabla, n):
        cur = target_db.cursor()
        cur.execute('select * from '+tabla+' limit 1')
        campos = cur.description
        cur.close()
        campos = campos[:n]
        campos = [campo[0] for campo in campos]
        return ','.join(campos)

ejecutasqlendestino(sql)

Ejecuta una consulta SQL en la base de datos de destino.

    def ejecutasqlendestino(sql):
        cur = target_db.cursor()
        cur.execute(sql)
        cur.close()
        print(' SQL Ejecutado :', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

pasartabla(source_table, target_table)

Migra una tabla completa de Oracle a MariaDB/MySQL.

  • Obtiene las columnas de la tabla origen.
  • Genera un SQL de inserción para la tabla de destino.
  • Copia los datos en bloques de 500 filas.
  • Vacía la tabla destino antes de insertar nuevos datos.
    def pasartabla(source_table, target_table):
        cur_select = source_db.cursor()
        cur_insert = target_db.cursor()
        cur_select.arraysize = 500
        cur_insert.arraysize = 500

        if source_db_type.upper() == 'ORACLE':
            get_column_length = 'select * from '+source_table+' where rownum<=1'
        elif source_db_type.upper() == 'MYSQL':
            get_column_length = 'select * from ' + source_table + ' limit 1'
        cur_select.execute(get_column_length)

        col_len = len(cur_select.fetchone())
        val_str = ''
        if target_db_type.upper() == 'MYSQL':
            for i in range(1, col_len):
                val_str = val_str+'%s'+','
            val_str = val_str+'%s'
        elif target_db_type.upper() == 'ORACLE':
            for i in range(1, col_len):
                val_str = val_str+':'+str(i)+','
            val_str = val_str+':'+str(col_len)

        campos = primerosncamposdelatabladestino(target_table, col_len)
        insert_sql = 'insert into '+target_table + ' (' + campos + ') values('+val_str+')'
        select_sql = 'select * from '+source_table
        cur_select.execute(select_sql)
        cur_insert.execute('TRUNCATE ' + target_table)

        while True:
            rows = list(cur_select.fetchmany(500))
            cur_insert.executemany(insert_sql, rows)
            target_db.commit()
            if not rows:
                break

        cur_select.close()
        cur_insert.close()
        print(' Tabla Migrada :', target_table, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

pasarsql(sql, target_table, where_eliminar)

Realiza una migración basada en una consulta SQL personalizada y elimina registros según una condición.

    def pasarsql(sql, target_table, where_eliminar):
        cur_select = source_db.cursor()
        cur_insert = target_db.cursor()
        cur_select.arraysize = 500
        cur_insert.arraysize = 500

        if source_db_type.upper() == 'ORACLE':
            get_column_length = sql + ' and rownum<=1'
        elif source_db_type.upper() == 'MYSQL':
            get_column_length = sql + ' limit 1'
        cur_select.execute(get_column_length)

        col_len = len(cur_select.fetchone())
        val_str = ''
        if target_db_type.upper() == 'MYSQL':
            for i in range(1, col_len):
                val_str = val_str+'%s'+','
            val_str = val_str+'%s'
        elif target_db_type.upper() == 'ORACLE':
            for i in range(1, col_len):
                val_str = val_str+':'+str(i)+','
            val_str = val_str+':'+str(col_len)

        campos = primerosncamposdelatabladestino(target_table, col_len)
        insert_sql = 'insert into '+target_table + ' (' + campos + ') values('+val_str+')'
        cur_insert.execute('DELETE FROM ' + target_table + where_eliminar)

        while True:
            rows = list(cur_select.fetchmany(500))
            cur_insert.executemany(insert_sql, rows)
            target_db.commit()
            if not rows:
                break

        cur_select.close()
        cur_insert.close()
        print(' Tabla Migrada :', target_table, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

parse_sql(filename)

Lee y divide un archivo .sql en múltiples consultas SQL.

def parse_sql(filename):
    data = open(filename, 'r').readlines()
    stmts = []
    DELIMITER = ';'
    stmt = ''

    for lineno, line in enumerate(data):
        if not line.strip():
            continue

        if line.startswith('--'):
            continue

        if 'DELIMITER' in line:
            DELIMITER = line.split()[1]
            continue

        if (DELIMITER not in line):
            stmt += line.replace(DELIMITER, ';')
            continue

        if stmt:
            stmt += line
            stmts.append(stmt.strip())
            stmt = ''
        else:
            stmts.append(line.strip())
    return stmts


ejecutaarchivosqlendestino(file_name)

Ejecuta todas las consultas de un archivo .sql en la base de datos destino.

def ejecutaarchivosqlendestino(file_name):
    stmts = parse_sql(file_name)
    with target_db.cursor() as cursor:
        for stmt in stmts:
            cursor.execute(stmt)
        target_db.commit()
    print(' Script Ejecutado:', file_name, ' ', time.strftime(
        "%Y-%m-%d %H:%M:%S", time.localtime()))

Ejecución de ejemplos

A continuación, algunos ejemplos de cómo se utiliza el script para migrar tablas del rolado de Oracle a MariaDB/MySQL:

# Migrar tablas completas, extrae todos los registros de la tabla origen, posteriormente trunca la tabla destino y la llena con los registros extraídos.
pasartabla('TABLA_ORIGEN', 'TABLA_DESTINO')

# Migrar datos específicos con consultas SQL, extrae los registros de la tabla origen que cumplan con la condición especificada en la consulta SQL, posteriormente elimina los registros de la tabla destino que cumplan con la condición especificada y llena la tabla destino con los registros extraídos.
pasarsql('SELECT * FROM TABLA_ORIGEN WHERE 1=1', 'TABLA_DESTINO', ' WHERE (1=1)')

# Ejecutar un archivo SQL en la base de datos destino para ajustar datos de los planes y cursos.
ejecutaarchivosqlendestino('scriptplanes.sql')

Cierre de conexiones

Finalmente, es importante cerrar las conexiones con las bases de datos después de ejecutar todas las operaciones:

source_db.close()
target_db.close()