Python SQLAlchemy-选择更新示例

Python SQLAlchemy-选择更新示例,python,sqlalchemy,select-for-update,Python,Sqlalchemy,Select For Update,我正在寻找一个在SQLAlchemy中使用select for update的完整示例,但还没有在Google上找到一个。我需要锁定一行并更新一列,以下代码不会永远起作用: s = table.select(table.c.user=="test",for_update=True) # Do update or not depending on the row u = table.update().where(table.c.user=="test") u.execute(em

我正在寻找一个在SQLAlchemy中使用select for update的完整示例,但还没有在Google上找到一个。我需要锁定一行并更新一列,以下代码不会永远起作用:

s = table.select(table.c.user=="test",for_update=True)
# Do update or not depending on the row
u = table.update().where(table.c.user=="test")         
u.execute(email="foo") 
我需要承诺吗?我该怎么做?据我所知,您需要: 开始交易 选择更新 使现代化
提交

是的,您确实需要提交,您可以在引擎上执行提交或明确创建事务。修改器也在值中指定。。。方法,而不执行:

迟来的回答,但也许有人会发现它有用

首先,您不需要提交,至少不需要在查询之间提交,我假设您正在询问。第二个查询无限期挂起,因为您实际上是在创建两个到数据库的并发连接。第一个是获取选定记录的锁,然后第二个尝试修改锁定的记录。所以它不能正常工作。顺便说一下,在给出的示例中,您根本没有调用第一个查询,因此我假设在您的实际测试中,您在某处执行了类似s.execute的操作。因此,到目前为止,工作实现应该更像:

s = conn.execute(table.select(table.c.user=="test", for_update=True))
u = conn.execute(table.update().where(table.c.user=="test"), {"email": "foo"})
conn.commit()

当然,在这种简单的情况下,没有理由进行任何锁定,但我想这只是示例,您计划在这两个调用之间添加一些附加逻辑。

如果您使用的是ORM,请尝试以下功能:

foo = session.query(Foo).filter(Foo.id==1234).with_for_update().one() # this row is now locked foo.name = 'bar' session.add(foo) session.commit() # this row is now unlocked
这个答案忽略了问题的要点,即选择。。。有关更新用法示例。它的代码可以简化为建议的形式,但是它不再使用请求的构造。当然,如果@Mark不打算在获取锁和更新记录之间添加任何额外的逻辑,那么这样的减少是完全可以做到的。还想指出查询对象对此有一个新方法:@MatthewMoisen你能告诉我为什么使用add吗?如果我不用,可以吗@小文件 您不需要使用add。在使用_for_update.one执行后,该行将被锁定,并在session.commit或session.rollback上解锁。 foo = session.query(Foo).filter(Foo.id==1234).with_for_update().one() # this row is now locked foo.name = 'bar' session.add(foo) session.commit() # this row is now unlocked