将 "on_conflict_do_update()" 与 sqlalchemy ORM 一起使用
Use "on_conflict_do_update()" with sqlalchemy ORM
我目前正在使用 SQLAlchemy ORM 来处理我的数据库操作。现在我有一个 SQL 命令需要 ON CONFLICT (id) DO UPDATE
。 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
的正确方法?
如 documentation 中所述,constraint=
参数是
The name of a unique or exclusion constraint on the table, or the constraint object itself if it has a .name attribute.
所以我们需要将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)
我目前正在使用 SQLAlchemy ORM 来处理我的数据库操作。现在我有一个 SQL 命令需要 ON CONFLICT (id) DO UPDATE
。 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
的正确方法?
如 documentation 中所述,constraint=
参数是
The name of a unique or exclusion constraint on the table, or the constraint object itself if it has a .name attribute.
所以我们需要将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)