我正在尝试使用此sqlalchemy命令显式锁定postgres表:
db.engine.execute('BEGIN; LOCK TABLE database_version IN ACCESS EXCLUSIVE MODE;')
执行此操作后,如果我进入数据库客户端并运行:
select * from pg_catalog.pg_locks;
目前没有任何ACCESS EXCLUSIVE锁。
如果相反,我运行第一个命令,但是从db客户端内部,它按预期工作。
是否有理由试图从sqlalchemy获取表锁无法正常工作?
理想情况下,我只希望一个进程能够一次查询并插入到database_version表中。
答案 0 :(得分:2)
事实证明,我需要从会话对象启动嵌套事务,而不是使用直接SQL尝试BEGIN
。
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()
答案 1 :(得分:0)
我相信锁定会话你可以使用查询session.query(database_version).with_lockmode(' update')
我仍在努力确认。
答案 2 :(得分:0)
with_lockmode("...") 现在在 sqlalchamy 中已弃用,请参阅此处的参考: https://kite.com/python/docs/sqlalchemy.orm.Query.with_lockmode
现在的解决方案是使用:
session.query(database_version).with_for_update()