Tan*_*lee 26 python sql-server bulkinsert pyodbc sql-server-2012
下面是我想要帮助的代码.我不得不运行超过1,300,000行,这意味着插入~300,000行需要40分钟.
我认为批量插入是加速它的路线?或者是因为我通过for data in reader:部分迭代行?
#Opens the prepped csv file
with open (os.path.join(newpath,outfile), 'r') as f:
#hooks csv reader to file
reader = csv.reader(f)
#pulls out the columns (which match the SQL table)
columns = next(reader)
#trims any extra spaces
columns = [x.strip(' ') for x in columns]
#starts SQL statement
query = 'bulk insert into SpikeData123({0}) values ({1})'
#puts column names in SQL query 'query'
query = query.format(','.join(columns), ','.join('?' * len(columns)))
print 'Query is: %s' % query
#starts curser from cnxn (which works)
cursor = cnxn.cursor()
#uploads everything by row
for data in reader:
cursor.execute(query, data)
cursor.commit()
Run Code Online (Sandbox Code Playgroud)
我是故意动态选择我的列标题(因为我想创建最可能的pythonic代码).
SpikeData123是表名.
Gor*_*son 41
如对另一个答案的评论中所述,T-SQL BULK INSERT命令仅在要导入的文件与SQL Server实例位于同一台计算机上或位于SQL Server实例可读取的SMB/CIFS网络位置时才有效.因此,它可能不适用于源文件位于远程客户端上的情况.
pyodbc 4.0.19添加了一个Cursor#fast_executemany功能,在这种情况下可能会有所帮助.fast_executemany默认为"关闭",以下测试代码......
cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("TRUNCATE TABLE fast_executemany_test")
sql = "INSERT INTO fast_executemany_test (txtcol) VALUES (?)"
params = [(f'txt{i:06d}',) for i in range(1000)]
t0 = time.time()
crsr.executemany(sql, params)
print(f'{time.time() - t0:.1f} seconds')
Run Code Online (Sandbox Code Playgroud)
...在我的测试机器上执行大约需要22秒.只需添加crsr.fast_executemany = True......
cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("TRUNCATE TABLE fast_executemany_test")
crsr.fast_executemany = True # new in pyodbc 4.0.19
sql = "INSERT INTO fast_executemany_test (txtcol) VALUES (?)"
params = [(f'txt{i:06d}',) for i in range(1000)]
t0 = time.time()
crsr.executemany(sql, params)
print(f'{time.time() - t0:.1f} seconds')
Run Code Online (Sandbox Code Playgroud)
...将执行时间缩短到1秒多一点.
Gor*_*son 36
BULK INSERT几乎肯定会多比阅读源文件一行一行地,做的每一行定期INSERT更快.但是,BULK INSERT和BCP都对CSV文件有很大的限制,因为它们无法处理文本限定符(参见此处).也就是说,如果您的CSV文件中没有合格的文本字符串...
1,Gord Thompson,2015-04-15
2,Bob Loblaw,2015-04-07
Run Code Online (Sandbox Code Playgroud)
...然后你可以BULK INSERT它,但如果它包含文本限定符(因为一些文本值包含逗号)...
1,"Thompson, Gord",2015-04-15
2,"Loblaw, Bob",2015-04-07
Run Code Online (Sandbox Code Playgroud)
...然后BULK INSERT无法处理它.但是,将这样的CSV文件预处理到管道分隔文件中总体上可能更快......
1|Thompson, Gord|2015-04-15
2|Loblaw, Bob|2015-04-07
Run Code Online (Sandbox Code Playgroud)
...或制表符分隔文件(其中BULK INSERT代表制表符)...
1?Thompson, Gord?2015-04-15
2?Loblaw, Bob?2015-04-07
Run Code Online (Sandbox Code Playgroud)
...然后BULK INSERT那个文件.对于后者(制表符分隔)文件,BULK INSERT代码看起来像这样:
import pypyodbc
conn_str = "DSN=myDb_SQLEXPRESS;"
cnxn = pypyodbc.connect(conn_str)
crsr = cnxn.cursor()
sql = """
BULK INSERT myDb.dbo.SpikeData123
FROM 'C:\\__tmp\\biTest.txt' WITH (
FIELDTERMINATOR='\\t',
ROWTERMINATOR='\\n'
);
"""
crsr.execute(sql)
cnxn.commit()
crsr.close()
cnxn.close()
Run Code Online (Sandbox Code Playgroud)
注意:如注释中所述,?只有在SQL Server实例可以直接读取源文件时才执行语句.对于源文件位于远程客户端的情况,请参阅此答案.
| 归档时间: |
|
| 查看次数: |
47926 次 |
| 最近记录: |