2016-05-03 17 views
5

W skrypcie python, muszę uruchomić kwerendę na jednym źródle danych i wstawić każdy wiersz z tego zapytania do tabeli w innym źródle danych. Zwykle robię to za pomocą pojedynczej instrukcji insert/select z połączeniem serwera połączonym przez tsql, ale nie mam połączonego połączenia z serwerem dla tego konkretnego źródła danych.Podstawowa wkładka hurtowa pyodbc

Mam problem ze znalezieniem prostego przykładu tego pyodbc. Oto, jak to zrobić, ale domyślam się, że wykonanie instrukcji insert w pętli jest dość powolne.

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

Czy istnieje lepszy sposób masowego wstawiania rekordów z pyodbc? Czy jest to względnie skuteczny sposób, aby to zrobić w każdym razie. Używam SqlServer 2012 i najnowszych wersji pyodbc i python.

Odpowiedz

7

Najlepszym sposobem radzenia sobie z tym problemem jest użycie funkcji pyodbc executemany.

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


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

Po prostu uwaga, executemany w rzeczywistości nie robi prawdziwej bulki. Za sceną nadal wkładka 1 przez 1. Jest to naprawdę wrapper, aby dane były zbierane bardziej pythonically. Ten post SO przedstawia prawidłową bulkinsert. http://stackoverflow.com/questions/29638136/how-to-speed-up-with-bulk-insert-to-ms-server-from-python-with-pyodbc-from-csv – casbby

4

Oto funkcja, która może wykonać zbiorczą wstawkę do bazy danych SQL Server.

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

To zdecydowanie działa. Z powodu aktualizacji lepiej używać pypyodbc zamiast pyodbc.

+1

To jest poprawna odpowiedź, i powinny być akceptowane jako takie. Metoda executemany nie zastępuje szybkości wstawiania zbiorczego. Uwaga: Jeśli chcesz wykonać zbiorczą wstawkę z iteratora zamiast pliku na samym serwerze SQL Server, opcją jest sterownik ctds. https://pypi.python.org/pypi/ctds/ – Kerr

+0

Tylko po prostu wyewidencjonowałeś podany link. Myślę, że wygląda naprawdę dobrze. Spróbuję. Dzięki. – Naufal