Postgresql 的 SQLalchemy 显式锁定 table

Sqlalchemy explicit locking of Postgresql table

我正在尝试使用此 sqlalchemy 命令显式锁定 postgres table:

db.engine.execute('BEGIN; LOCK TABLE database_version IN ACCESS EXCLUSIVE MODE;')

执行后,如果我进入数据库客户端并 运行:

select * from pg_catalog.pg_locks;

不存在任何 ACCESS EXCLUSIVE 锁。

如果相反,我 运行 第一个命令,但是从数据库客户端内部,它按预期工作。

尝试从 sqlalchemy 获取 table 锁是否无法正常工作是有原因的吗?

理想情况下,我希望一次只有一个进程能够从 database_version table 中查询和插入。

所以事实证明我需要从会话对象开始嵌套事务,而不是尝试 BEGIN 使用直接 SQL。

db.session.begin_nested()
db.session.execute('LOCK TABLE database_version IN ACCESS EXCLUSIVE MODE;')

然后,我插入新行:

new_version = DatabaseVersion(version=version + 1)
db.session.add(new_version)
db.session.commit()

然后最后再次提交以关闭嵌套事务:

db.session.commit()

with_lockmode("...") 现在已在 sqlalchamy 中弃用,请参阅此处的参考资料: https://kite.com/python/docs/sqlalchemy.orm.Query.with_lockmode

现在的解决方案是使用:

session.query(database_version).with_for_update()