重要细节:
- mysql-connector-python==8.0.18
- 我正在使用 pypy3,它作为 Python3 的替代实现
- bulk_data 列表中的每一项都是一个 dict 对象,有两项,每个 key 小于 10 个字符,每个 value 不超过 40 个字符。
目前,我有一个大约 25k 条记录的记录集,其中包含两条数据。我正在尝试使用此信息更新我的数据库中的行,但无论我尝试什么,我都会收到“执行多个语句时使用 multi=True”作为错误。
奇怪之处如下: 1. 我已经尝试使用executemany(sql,data_set)将其作为批量数据集。这不能使用“multi=True” 2. 我已将其分解为单个更新并使用 execute(sql, multi=True)
我在下面使用“executemany”提供了一个代码示例,假设 bulk_data 是我的数据集的一个小版本:
bulk_data = [{'item_1':"TEST", 'item_2':"TEST2"}, {'item_1':"TEST3", 'item_2':"TEST4"}]
self.setup_mysql_con()
cursor = self._mysql.cursor()
update_sql = """
UPDATE `db_name`.`db_table`
SET `column_1` = %(item_1)s
WHERE `column_2` = %(item_2)s;
"""
try:
cursor.executemany(update_sql, bulk_data)
self._mysql.commit()
except Exception as es:
self.print(str(es))
self.print('[{}] Error updating records in DB.'.format(
time.strftime("%H:%M:%S", time.localtime())))
pass
cursor.close()
self.close_mysql()
我保留上述内容是因为它是一个应该工作的代码示例,如果需要,我可以恢复。以下是当前设置该过程的工作方式。
group_count = 1000
loop_num = 1
count = 0
total = len(data_list)
if total > 0:
self.setup_mysql_con()
cursor = self._mysql.cursor(buffered=True)
while count < total:
sub_data = data_list[(loop_num - 1) * group_count: loop_num * group_count]
count = count + len(sub_data)
update_sql = ""
for data in sub_data:
update_sql = update_sql + "UPDATE `db_name`.`db_table` SET `column` = '{}'
WHERE `column_2` = '{}';\n".format(
data['column_data'],
data['column2_data']
)
loop_num = loop_num + 1
try:
for result in cursor.execute(update_sql, multi=True):
if result.with_rows:
self.fprint("Rows produced by statement '{}':".format(result.statement))
else:
self.fprint("Number of rows affected by statement '{}': {}".format(result.statement, result.rowcount))
self._mysql.commit()
except Exception as es:
self.fprint(str(es))
pass
cursor.close()
self.close_mysql()
上述代码在第四个左右循环之后的错误,并不总是相同的: 使用 cmd_query_iter for statements with multiple queries。
您可以假设上面的更新文本是 100% 正确的。可以肯定的是,我还将我的 SQL 语句导出到一个文本文件中,然后我在我的数据库中运行该文件以确保获得正确的结果,并且确实如此。然而,这不是一个可扩展的解决方案,我正在自动化这个过程,所以通过 cron 启动它的能力很重要。