似乎Django
' queryset.update
方法在transaction.atomic
上下文管理器下执行。我何时需要在update
期间在我的代码中明确地执行此操作?或者这样做有什么好处,或者没有做到的问题呢?
try:
queryset = Model.objects.filter(a=1)
if queryset.count():
with transaction.atomic():
queryset.update(a=2) # queryset will [] after this.
for item in queryset:
item.emit_event('Updated')
except:
logger.info('Exception')
我的问题是我真的需要transaction.atomic():
吗?
其次,在.update
之后,我的queryset变为空,因为它是一个过滤的查询集。如何在我的情况下保留值,因为我想在各个对象上发出一个事件。
答案 0 :(得分:1)
<强>第一强>
作为docs州
Atomicity是数据库事务的定义属性。 atomic允许我们创建一个代码块,在该代码块中保证数据库的原子性。如果代码块成功完成,则更改将提交到数据库。如果存在异常,则会回滚更改。
在您的示例中,如果atomic
正在执行某项操作,您需要emit_event
,并且只有在所有emit_event
函数调用和queryset.update
成功完成时才希望执行此更新。但是,如果emit_event
的状态不会影响您的更新业务逻辑,atomic
此处将是多余的,因为正如您所说update
有内部atomic
。
<强>第二强>
查询集很懒惰。这意味着当您迭代查询集时,将对其进行评估。所以你需要做这样的事情。回答最新评论
try:
queryset = Model.objects.filter(a=1)
item_ids = list(queryset.values_list('id', flat=True)) # store ids for later
if item_ids: # optimzing here instead of queryset.count() so there won't be hit to DB
with transaction.atomic():
queryset.update(a=2) # queryset will [] after this.
for item in Model.objects.filter(id__in=item_ids): # <- new queryset which gets only updated objects
item.emit_event('Updated')
except:
logger.info('Exception')
看到我们在迭代它时获取新的查询集以获取更新的项目