Faster solution than executemany to insert multiple rows at once in pyodbc
我想用一个插入语句插入多行。
我尝试过
1 2 3 4 | params = ((1, 2), (3,4), (5,6)) sql = 'insert into tablename (column_name1, column_name2) values (?, ?)' cursor.fast_executemany = True cursor.executemany(sql, params) |
但这是在后台运行execute方法的参数上的简单循环。
我还尝试创建更长的insert语句,使其类似于INSERT INTO表名(col1,col2)VALUES(?,?),(?,?)...(?,?)。
1 2 3 4 5 6 | def flat_map_list_of_tuples(list_of_tuples): return [element for tupl in list_of_tuples for element in tupl]) args_str = ', '.join('(?,?)' for x in params) sql = 'insert into tablename (column_name1, column_name2) values' db.cursor.execute(sql_template + args_str, flat_map_list_of_tuples(params)) |
有效,插入时间从10.9s减少到6.1。
此解决方案正确吗?它有一些漏洞吗?
Is this solution correct?
您建议的解决方案是构建表值构造函数(TVC),这不是不正确的,但实际上不是必需的。具有
Does it have some vulnerabilities?
由于您正在为参数化查询构建TVC,因此可以防止SQL注入漏洞,但是仍需考虑一些实现注意事项:
TVC一次最多可以插入1000行。
pyodbc通过调用系统存储过程来执行SQL语句,并且SQL Server中的存储过程最多可以接受2100个参数,因此TVC可以插入的行数也限制为(number_of_rows * number_of_columns <2100)。
换句话说,您的TVC方法将被限制为1000行或更少的"块大小"。实际计算在此答案中描述。