在 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_updaterelies 的实现与我上面提供的解决方案完全相同的 Case/When/Then/Value 恶作剧。

【讨论】:

以上是关于在 Django 中更新查询集中的一堆记录的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

从 django 的查询集中获取第一个对象的最快方法?

Django:从查询集中删除过滤条件

在 MS Access 中,创建动态查询后,如何使用记录集中的相应值更新表单上的文本框?

Django:更改查询集中所有对象的字段值

获取查询集中的最后一条记录

使用 Django 在数据库中获取不需要的特定记录的最快方法