在 Django 中更新查询集中的一堆记录的最快方法
Posted
技术标签:
【中文标题】在 Django 中更新查询集中的一堆记录的最快方法【英文标题】:Fastest Way to Update a bunch of records in queryset in Django 【发布时间】:2011-01-09 15:37:10 【问题描述】:我有一个包含几百万条记录的查询集。我需要更新一个布尔值,从根本上切换它,以便在数据库表中重置值。最快的方法是什么?
我尝试遍历查询集并更新和保存每条记录,这显然需要很长时间?我们需要非常快地完成这项工作,有什么建议吗?
【问题讨论】:
【参考方案1】:见documentation:
Entry.objects.all().update(value= not F('value'))
【讨论】:
【参考方案2】:实际上,这对我来说并不奏效。
做了以下事情:
Entry.objects.all().update(value=(F('value')==False))
【讨论】:
【参考方案3】:实际上,建议的解决方案都没有奏效。我相信他们在某个时候确实有效,但现在不再有效了。
问题在于 Django 将 not F('value')
评估为 False。
您可以通过在 python shell 中测试来自己尝试一下
not F('is_featured')
对比
for example F('is_featured') + 1
这是因为 Django 不支持 F 表达式中的否定/非。 Here 是关于这个话题的讨论:讨论了很多,但最后这个问题没有得到解决。 8 年了。
幸运的是,有一个解决方案。我找到了here。 你必须使用Case When
from django.db.models import Case, Value, When
Item.objects.filter(serial__in=license_ids
).update(renewable=Case(
When(renewable=True, then=Value(False)),
default=Value(True))
)
)
有时你might want to usebulk_update
而不是普通的update
。
有趣的是,bulk_update
relies 的实现与我上面提供的解决方案完全相同的 Case/When/Then/Value 恶作剧。
【讨论】:
以上是关于在 Django 中更新查询集中的一堆记录的最快方法的主要内容,如果未能解决你的问题,请参考以下文章