2016-05-03 24 views
5

在python脚本中,我需要在一个数据源上运行查询,并将该查询的每一行插入到不同数据源的表中。我通常会用一个带有tsql链接服务器连接的插入/选择语句执行此操作,但是我没有链接到此特定数据源的链接服务器连接。基本的pyodbc批量插入

我无法找到一个简单的pyodbc这个例子。这里是我怎么做,但我猜在循环内执行插入语句是非常缓慢的。

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

是否有更好的批量方式插入记录与pyodbc?或者这是一个相对有效的方式来做到这一点。我使用的是SqlServer 2012,以及最新的pyodbc和python版本。

回答

7

处理此问题的最佳方法是使用pyodbc函数executemany

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


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

只是说明,executemany实际上并没有真正做bulkinsert。在场景的后面,插入1仍然是1.它真的是一个包装,允许数据更加pythonically来源。这SO帖子提出了一个适当的bulkinsert。 http://stackoverflow.com/questions/29638136/how-to-speed-up-with-bulk-insert-to-ms-server-from-python-with-pyodbc-from-csv – casbby

4

这是一个可以批量插入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() 

这绝对有效。由于更新,最好使用pypyodbc而不是pyodbc。

+1

这是正确的答案,并应该被接受。 executemany方法不能替代批量插入的速度。值得注意的是,如果你想从迭代器中执行批量插入而不是SQL Server本身的文件,那么ctds驱动程序是一个选项。 https://pypi.python.org/pypi/ctds/ – Kerr

+0

只检出您提供的链接。我认为它看起来非常好。要试一试。谢谢。 – Naufal