sqlalchemy 使用元组列表更新

sqlalchemy update using list of tuples

在 sqlalchemy 中是否有一种基于元组列表更新行的有效方法? 如果它是单行,那么我可以简单地做:

session.query(table).filter(table.id == 10).update({'values': 'x'})
session.commit

然而,我得到的数据是一个元组列表

[(10, 'x'),(20,'y'),(30,'z'),(40,'p')]

table 有 ID 10,20,30,40 等等

是否有有效的更新方式来代替多个单独的更新?

您可以将元组列表转换为字典列表,然后将 update()bindparam() 一起使用,如 tutorial:

中所示
from pprint import pprint

import sqlalchemy as sa

engine = sa.create_engine("sqlite://")

tbl = sa.Table(
    "tbl",
    sa.MetaData(),
    sa.Column("id", sa.Integer, primary_key=True, autoincrement=False),
    sa.Column("value", sa.String(50)),
)
tbl.create(engine)

with engine.begin() as conn:
    conn.execute(
        tbl.insert(),
        [
            {"id": 10, "value": "old_10"},
            {"id": 20, "value": "old_20"},
            {"id": 30, "value": "old_30"},
        ],
    )

with engine.begin() as conn:
    # initial state
    print(conn.execute(sa.select(tbl)).all())
    # [(10, 'old_10'), (20, 'old_20'), (30, 'old_30')]

    new_data = [(10, "x"), (20, "y"), (30, "z")]

    params = [dict(tbl_id=a, new_value=b) for (a, b) in new_data]
    pprint(params, sort_dicts=False)
    """
    [{'tbl_id': 10, 'new_value': 'x'},
     {'tbl_id': 20, 'new_value': 'y'},
     {'tbl_id': 30, 'new_value': 'z'}]
    """

    upd = (
        sa.update(tbl)
        .values(value=sa.bindparam("new_value"))
        .where(tbl.c.id == sa.bindparam("tbl_id"))
    )
    print(upd)
    # UPDATE tbl SET value=:new_value WHERE tbl.id = :tbl_id

    conn.execute(upd, params)

    # check results
    print(conn.execute(sa.select(tbl)).all())
    # [(10, 'x'), (20, 'y'), (30, 'z')]