Sqlalchemy显式锁定Postgresql表

时间:2016-05-19 18:44:27

标签: python postgresql sqlalchemy locking

我正在尝试使用此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表中。

3 个答案:

答案 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()