2016-05-03 11 views
5

In einem Python-Skript muss ich eine Abfrage auf einer Datenquelle ausführen und jede Zeile aus dieser Abfrage in eine Tabelle auf einer anderen Datenquelle einfügen. Normalerweise würde ich dies mit einer einzelnen insert/select-Anweisung mit einem tsql-Verbindungsserver-Join tun, aber ich habe keine Verbindungsserververbindung zu dieser bestimmten Datenquelle.Basic pyodbc Masseneinfügung

Ich habe Probleme, ein einfaches Pyodbc Beispiel dafür zu finden. Hier ist, wie ich es tun würde, aber ich denke, das Ausführen einer Insert-Anweisung in einer Schleife ist ziemlich langsam.

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() 

Gibt es einen besseren Massenweg, um Datensätze mit pyodbc einzufügen? Oder ist dies eine relativ effiziente Möglichkeit, dies zu tun? Ich verwende SqlServer 2012 und die neuesten pyodbc- und python-Versionen.

Antwort

7

Der beste Weg, dies zu umgehen, ist die Verwendung der Pyodbc-Funktion executemany.

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


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

Nur eine Anmerkung, Executemany tut nicht wirklich Bulkinsert. Hinter der Szene tut es immer noch das Insert 1 mal 1. Es ist wirklich ein Wrapper, um Daten pythonhaltiger zu erhalten. Dieser SO Post stellt eine richtige bulkwersert dar. http://stackoverflow.com/questions/29638136/how-to-speed-up-with-bulk-insert-to-ms-server-from-python-with-pyodbc-from-csv – casbby

4

Hier ist eine Funktion, die die Masseneinfügung in die SQL Server-Datenbank durchführen kann.

import pypyodbc 
import contextlib 

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

Dies funktioniert definitiv. Aufgrund von Updates ist es besser, pypyodbc anstelle von pyodbc zu verwenden.

+1

Dies ist die richtige Antwort, und sollte als solche akzeptiert werden. Die Executemany-Methode ersetzt nicht die Geschwindigkeit der Masseneinfügung. Wenn Sie eine Masseneinfügung von einem Iterator statt einer Datei auf dem SQL Server selbst durchführen möchten, ist der Ctds-Treiber eine Option. https://pypi.python.org/pypi/ctds/ – Kerr

+0

Nur den Link, den Sie angegeben haben, ausgecheckt. Ich denke, es sieht wirklich gut aus. Ich werde es versuchen. Vielen Dank. – Naufal