在SQLAlchemy中使用许多记录优化Update语句

时间:2017-05-04 18:12:31

标签: python mysql google-app-engine sqlalchemy

我正在尝试使用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)

1 个答案:

答案 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 )。