使用mysql高效地更新python字典列表

von4xj4u  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(425)

假设有一个mysql表“user”。
假设一个单列主键“id”。
假设要插入的数据始终以字典列表的形式给出,格式如下: [{'column_name1':'valueA', 'column_name2':'valueB'}, {'column_name1':'valueC', 'column_name2':'valueD'}]. 如果插入的行具有相同的主键(aka id),我只想更新所有其他列的值。

data1 = [{'id': 1, 'name': 'flo', 'role': 'admin', 'number': 121, 'text': 'text1'}, {'id': 2, 'name': 'foo', 'role': 'user', 'number': 567, 'text': 'text2'}, {'id': 3, 'name': 'banana', 'role': 'user', 'number': 890, 'text': 'text3'}]
data2 = [{'id': 3, 'name': 'bar', 'role': 'user', 'number': 56777, 'text': 'text4'}, {'id': 4, 'name': 'james', 'role': 'user', 'number': 999890, 'text': 'text5'}]

from sqlalchemy import create_engine
from sqlalchemy import MetaData
from sqlalchemy import Table

engine = create_engine(connectionString)
metadata = MetaData(engine)
table = Table('user', metadata, autoload=True)

# assuming user table is empty

engine.execute(table.insert(), data1)
bulk_insert = prepare_bulk_upsert_statement(data2)
engine.execute(bulk_insert)

我知道sqlalchemy确实有一个on_replicate_key_update方法,我可以在sqlalchemy.dialogs.mysql.insert中使用。但是从这个例子中,我无法理解prepare\u bulk\u upsert\u语句函数是什么样子的。最终,用户表的内容应如下所示:

query = table.select()  
print ([r._asdict() for r in engine.execute(query)])

>
[{'id': 1, 'name': 'flo', 'role': 'admin', 'number': 121, 'text': 'text1'},  
{'id': 2, 'name': 'foo', 'role': 'user', 'number': 567, 'text': 'text2'},
{'id': 3, 'name': 'bar', 'role': 'user', 'number': 56777, 'text': 'text4'},
{'id': 4, 'name': 'james', 'role': 'user', 'number': 999890, 'text': 'text5'}]

查看sqlalchemy示例:

from sqlalchemy.dialects.mysql import insert
insert_stmt = insert(my_table).values(
     id='some_existing_id',
     data='inserted value')

on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(
    data=insert_stmt.inserted.data,
    status='U'
)

似乎on_duplicate_key_update只能处理一行(即一个字典)。有没有一种有效的方法可以使用这种方法进行升级?还是有更好的方法?

k75qkfdt

k75qkfdt1#

我是这样说的:

insert_stmt = insert(table).values(data2)
        primKeyColNames = [pk_column.name for pk_column in table.primary_key.columns.values()]
        updatedColNames = [column.name for column in table.columns if column.name not in primKeyColNames]
        onDuplicate = {colName:getattr(insert_stmt.inserted, colName) for colName in updatedColNames}
        on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(onDuplicate)
        engine.execute(on_duplicate_key_stmt)

获取主键(可以是多个列),将它们从列列表中删除,使用该列表为on_duplicate_key_update创建dict并将其传递给执行。

相关问题