我试图以原子方式更新查询集的字段。我有这样的事情:
counter = 0
for row in myQuerySet:
row.myField = counter
counter = counter + 1
row.save()
这是有效的,但我想原子地这样做,因为我有数百个寄存器,这是浪费时间。我需要这样的东西:
counter = 0
myQuerySet.update(myField=(counter+=1))
但这不起作用。什么是正确的sintax?
答案 0 :(得分:4)
这有效,但我想原子地做这个[...]
通常,答案是使用QuerySet.update
method。当您想要对查询集中的所有实例执行相同的操作(或者不需要动态更改的内容)时,这是有效的。
由于您要执行的操作似乎需要依次动态更改每个实例,因此您可以使用select_for_update
method。
from django.db import transaction
dolors = LoremIpsum.objects.select_for_update().filter(dolor=True)
with transaction.atomic():
counter = 0
for lorem_ipsum in dolors:
lorem_ipsum.amet = counter
counter += 1
lorem_ipsum.save()
documentation for select_for_update
说这可以做你想要的:
所有匹配的条目将被锁定,直到事务块结束,这意味着将阻止其他事务更改或获取锁定。
因为查询集导致项目“锁定到事务块结束”,所以您需要使用上面的transaction.atomic
在事务块内执行操作。