web-dev-qa-db-fra.com

insert en vrac de base pyodbc

Dans un script python, je dois exécuter une requête sur une source de données et insérer chaque ligne de cette requête dans une table sur une source de données différente. Je le ferais normalement avec une seule insertion/sélection avec une jointure de serveur lié tsql mais je n'ai pas de connexion de serveur lié à cette source de données particulière.

J'ai du mal à trouver un exemple simple de pyodbc. Voici comment je le ferais, mais je suppose que l'exécution d'une instruction d'insertion dans une boucle est assez lente.

result = ds1Cursor.execute(selectSql)

for row in result:
    insertSql = "insert into TableName (Col1, Col2, Col3) values (?, ?, ?)"
    ds2Cursor.execute(insertSql, row[0], row[1], row[2])
    ds2Cursor.commit()

Existe-t-il un meilleur moyen en vrac d'insérer des enregistrements avec pyodbc? Ou est-ce une façon relativement efficace de le faire de toute façon. J'utilise SqlServer 2012, et les dernières versions de pyodbc et python.

12
Zip184

La meilleure façon de gérer cela est d'utiliser la fonction pyodbc executemany.

ds1Cursor.execute(selectSql)
result = ds1Cursor.fetchall()


ds2Cursor.executemany('INSERT INTO [TableName] (Col1, Col2, Col3) VALUES (?, ?, ?)', result)
ds2Cursor.commit()
12
LegendaryDude

Voici une fonction qui peut effectuer l'insertion en bloc dans la base de données SQL Server.

import pyodbc
import contextlib

def bulk_insert(table_name, file_path):
    string = "BULK INSERT {} FROM '{}' (WITH FORMAT = 'CSV');"
    with contextlib.closing(pyodbc.connect("MYCONN")) as conn:
        with contextlib.closing(conn.cursor()) as cursor:
            cursor.execute(string.format(table_name, file_path))
        conn.commit()
        conn.close()

Cela fonctionne vraiment.

MISE À JOUR: J'ai remarqué dans les commentaires, ainsi que le codage régulièrement, que pyodbc est mieux pris en charge que pypyodbc.

9
Naufal