es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Ejecutando funciones SQL de valor escalar en Python

Estoy preguntándome cómo se puede ejecutar una función de SQL escalar en Python. Tengo una función que “limpia” una cadena dada (es decir, elimina caracteres especiales/espacios adicionales, etc.). El método actual que utilizo es el siguiente:

def cleanup(df):
    server87 = """
    DRIVER={{ODBC Driver 17 for SQL Server}};
    SERVER={};
    DATABASE={};
    Trusted_Connection=yes;
    """.format("server-87", "test_prod")

    cnxn = pyodbc.connect(server87)
    curr = cnxn.cursor()
    cnxn.execute("""
        create table #tmp_std_file (
            row_id int NOT NULL IDENTITY(1,1),
            name varchar(max)
        )
    """)

    names = df['NAMES'].to_list()              
    curr.executemany("""
        INSERT INTO #tmp_std_file
        VALUES (test_prod.dbo.name_cleanup(?))
    """,
    map(lambda x: [x], names),
    )
    curr.commit()
    rows = cnxn.execute("SELECT name FROM #tmp_std_file ORDER BY row_id")
    lisrows = [row.name for row in rows]
    return lisrows

Paso el dataframe y devuelve ‘lisrows’, que es la lista de nombres limpios. Mi pregunta es si hay una forma más rápida de hacer esto. Siento que escribir en una tabla, ejecutar y luego leer esa tabla lleva mucho tiempo.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma más rápida de ejecutar una función SQL escalar en Python. En lugar de escribir en una tabla temporal y luego leer de esa tabla, puedes llamar directamente a la función SQL escalar en Python usando una instrucción SELECT.

    Aquí tienes un ejemplo de fragmento de código:

    def cleanup(df):
        server87 = """
            DRIVER={{ODBC Driver 17 for SQL Server}};
            SERVER={server_name};
            DATABASE={database_name};
            Trusted_Connection=yes;
            """.format(
            server_name="server-87",
            database_name="test_prod"
        )
    
        cnxn = pyodbc.connect(server87)
        curr = cnxn.cursor()
    
        names = df['NAMES'].to_list()      
        clean_names = []
        for name in names:
            curr.execute("SELECT test_prod.dbo.name_cleanup(?)", name)
            result = curr.fetchone()[0]
            clean_names.append(result)
    
        return clean_names
    

    En lugar de escribir en una tabla temporal, este código utiliza un bucle para llamar a la función SQL escalar para cada nombre en el dataframe. La función se llama utilizando una instrucción SELECT, que devuelve el nombre limpio como resultado. El resultado se añade a una lista de nombres limpios, que se devuelve desde la función.

    Este enfoque debería ser más rápido que escribir en una tabla temporal y luego leer de esa tabla, ya que evita la sobrecarga de escribir en y leer de disco.

Comments are closed.