【问题标题】:Use "on_conflict_do_update()" with sqlalchemy ORM将“on_conflict_do_update()”与 sqlalchemy ORM 一起使用
【发布时间】:2022-01-12 14:37:47
【问题描述】:

我目前正在使用 SQLAlchemy ORM 来处理我的数据库操作。现在我有一个需要ON CONFLICT (id) DO UPDATE 的SQL 命令。 on_conflict_do_update() 方法似乎是正确的方法。但是the post here 表示代码必须切换到 SQLAlchemy 核心,并且缺少高级 ORM 功能。我对这种说法感到困惑,因为我认为像下面的演示这样的代码可以在保持 SQLAlchemy ORM 的功能的同时实现我想要的。

class Foo(Base):
  ...
  bar = Column(Integer)


foo = Foo(bar=1)


insert_stmt = insert(Foo).values(bar=foo.bar)
do_update_stmt = insert_stmt.on_conflict_do_update(
    set_=dict(
        bar=insert_stmt.excluded.bar,
    )
)

session.execute(do_update_stmt)

我没有在我的项目中测试过它,因为它需要大量的修改。请问这是否是使用 SQLALchemy ORM 处理ON CONFLICT (id) DO UPDATE 的正确方法?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    documentation 中所述,constraint= 参数是

    表上唯一或排除约束的名称,或约束对象本身(如果它具有 .name 属性)的名称。

    所以我们需要将 PK 约束的名称传递给.on_conflict_do_update()

    我们可以通过检查接口获取PK约束名称:

    insp = inspect(engine)
    pk_constraint_name = insp.get_pk_constraint(Foo.__tablename__)["name"]
    print(pk_constraint_name)  # tbl_foo_pkey
    
    new_bar = 123
    insert_stmt = insert(Foo).values(id=12345, bar=new_bar)
    do_update_stmt = insert_stmt.on_conflict_do_update(
        constraint=pk_constraint_name, set_=dict(bar=new_bar)
    )
    
    with Session(engine) as session, session.begin():
        session.execute(do_update_stmt)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-30
      • 2020-06-14
      • 1970-01-01
      • 2015-01-05
      • 2019-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多