我正在尝试使用SQLAlchemy一次更新许多记录,但我发现它非常慢。有没有最佳方式来执行此操作?
作为参考,我正在对40,000条记录进行更新,大约需要1小时。
以下是我正在使用的代码。 table_name 是指加载的表,列是要更新的单个列,对是指主要的列的键和新值。
def update_records(table_name, column, pairs):
table = Table(table_name, db.MetaData, autoload=True,
autoload_with=db.engine)
conn = db.engine.connect()
values = []
for id, value in pairs:
values.append({'row_id': id, 'match_value': str(value)})
stmt = table.update().where(table.c.id == bindparam('row_id')).values({column: bindparam('match_value')})
conn.execute(stmt, values)
答案 0 :(得分:1)
将参数列表传递给execute()
基本上会发出40k个UPDATE
语句,这会产生很多开销。解决方案是增加每个查询的行数。对于MySQL,这意味着插入临时表然后进行更新:
# assuming temp table already created
conn.execute(temp_table.insert().values(values))
conn.execute(table.update().values({column: temp_table.c.match_value})
.where(table.c.id == temp_table.c.row_id))
或者,您也可以使用INSERT ... ON DUPLICATE KEY UPDATE
来避免创建临时表,但SQLAlchemy本身不支持这种情况,因此您需要为此使用自定义编译的构造(例如this gist )。