使用原子计数更新查询集中的每个实例
Update every instance in a queryset with a count atomically
我正在尝试以原子方式更新查询集的字段。我有这样的东西:
counter = 0
for row in myQuerySet:
row.myField = counter
counter = counter + 1
row.save()
可行,但我想以原子方式执行此操作,因为我有数百个寄存器,这是浪费时间。我需要这样的东西:
counter = 0
myQuerySet.update(myField=(counter+=1))
但这不起作用。正确的语法是什么?
That works, but I want to do this atomically […]
通常,答案是使用 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
说这就是你想要的:
All matched entries will be locked until the end of the transaction block, meaning that other transactions will be prevented from changing or acquiring locks on them.
因为查询集导致项目“锁定到事务块结束”,您需要使用上述 transaction.atomic
在事务块内执行操作。
我正在尝试以原子方式更新查询集的字段。我有这样的东西:
counter = 0
for row in myQuerySet:
row.myField = counter
counter = counter + 1
row.save()
可行,但我想以原子方式执行此操作,因为我有数百个寄存器,这是浪费时间。我需要这样的东西:
counter = 0
myQuerySet.update(myField=(counter+=1))
但这不起作用。正确的语法是什么?
That works, but I want to do this atomically […]
通常,答案是使用 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
说这就是你想要的:
All matched entries will be locked until the end of the transaction block, meaning that other transactions will be prevented from changing or acquiring locks on them.
因为查询集导致项目“锁定到事务块结束”,您需要使用上述 transaction.atomic
在事务块内执行操作。