gpt4 book ai didi

python - PonyORM (Python) "Value was updated outside of current transaction"但事实并非如此

转载 作者:行者123 更新时间:2023-12-01 03:31:57 26 4
gpt4 key购买 nike

我正在使用 Pony ORM 版本 0.7 和磁盘上的 Sqlite3 数据库,并遇到此问题:我正在执行选择,然后更新,然后选择,然后另一个更新,并收到错误消息

pony.orm.core.UnrepeatableReadError: Value of Task.order_id for
Task[23654] was updated outside of current transaction (was: 1, now: 2)

我已将问题减少到导致问题的最小命令集(即删除任何内容会导致问题不再发生):

@db_session
def test_method():
tasks = list(map(Task.to_dict, Task.select()))
db.execute("UPDATE Task SET order_id=order_id*2")
task_to_move = select(task for task in Task if task.order_id == 2).first()
task_to_move.order_id = 1

test_method()

为了完整起见,以下是Task的定义:

class Task(db.Entity):
text = Required(unicode)
heading = Required(int)
create_timestamp = Required(datetime)
done_timestamp = Optional(datetime)
order_id = Required(int)

此外,如果我从选择中删除 task.order_id == 2 的约束,问题就不会再出现,所以我认为问题与基于以下字段的查询有关:自事务启动以来已更改,但我不知道为什么错误消息告诉我它已被不同的事务更改(除非 db.execute 可能在单独的事务中执行,因为这是原始 SQL?)

我已经看过这个类似的问题,但问题是不同的( Pony ORM reports record "was updated outside of current transaction" while there is not other transaction )和本文档( https://docs.ponyorm.com/transactions.html ),但都没有解决我的问题。

你知道这里会发生什么吗?

最佳答案

Pony 默认使用乐观并发控制。对于每个属性,Pony 都会记住其当前值(可能由应用程序代码修改)以及从数据库读取的原始值。在 UPDATE 期间,Pony 检查数据库中列的值是否仍然相同。如果该值发生更改,Pony 会假设某个并发事务执行了此操作,并抛出异常以避免“丢失更新”情况。

如果您执行一些原始 SQL 查询,Pony 不知道数据库中到底修改了什么。因此,当 Pony 遇到计数器值被更改时,它会错误地认为该值被另一笔交易更改。

为了避免这个问题,您可以将order_id属性标记为 volatile 。然后 Pony 会假设属性的值可以随时更改(通过触发器或原始 SQL 更新),并将该属性从乐观检查中排除:

class Task(db.Entity):
text = Required(unicode)
heading = Required(int)
create_timestamp = Required(datetime)
done_timestamp = Optional(datetime)
order_id = Required(int, volatile=True)

请注意,Pony 会缓存 volatile 属性的值,并且在保存对象之前不会重新从数据库读取该值,因此在某些情况下,您可以在 Python 中获取过时的值。

更新:

从版本 0.7.4 开始,您还可以为 db_session 指定 optimistic=False 选项,以关闭对使用原始 SQL 查询的特定事务的乐观检查:

with db_session(optimistic=False):
...

@db_session(optimistic=False)
def some_function():
...

现在还可以为属性指定 optimistic=False 选项,而不是指定 volatile=True。那么 Pony 不会对该属性进行乐观检查,但仍会考虑将其视为非 volatile

关于python - PonyORM (Python) "Value was updated outside of current transaction"但事实并非如此,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40871284/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com