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变得空,因为它是一个过滤的queryset。如何在我的情况下保留这些值,因为我想在各个对象上发出一个事件。
发布于 2016-08-30 23:25:48
First
As 文档状态
原子性是数据库事务的定义属性。原子允许我们创建一个代码块,在其中保证数据库的原子性。如果代码块已成功完成,则将更改提交到数据库。如果有异常,则回滚更改。
在您的示例中,如果atomic
正在执行某些操作,则需要emit_event
,并且只有在所有emit_event
函数调用和queryset.update
都成功的情况下,才需要执行此更新。但是,如果emit_event
的状态不影响更新的业务逻辑,那么这里的atomic
将是多余的,因为正如您自己所说的,update
有内部atomic
。
第二
Queryset很懒。这意味着查询集的评估将在迭代时完成。所以你需要做这样的事。回答最新评论
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')
请看,我们在迭代时创建新的queryset以获得更新的项。
https://stackoverflow.com/questions/39242799
复制