在Django中快速更新查询集中的多个记录的方法

7 投票
3 回答
2081 浏览
提问于 2025-04-15 18:30

我有一个查询结果,里面有几百万条记录。我需要更新一个布尔值,简单来说就是把它的值切换一下,让数据库表里的值重置。有什么最快的方法可以做到这一点呢?

我试着一个一个遍历这个查询结果,更新并保存每条记录,但这样显然太慢了。我们需要快速完成这个操作,有什么建议吗?

3 个回答

0

其实,之前提到的解决办法都没用。我觉得它们之前是有效的,但现在不行了。

问题在于,Django会把not F('value')当作False来处理。你可以在Python的命令行里自己试试。

not F('is_featured')

和下面这个比起来:

for example F('is_featured') + 1

之所以会这样,是因为Django在F表达式中不支持取反/not。这里有关于这个话题的讨论:讨论了很多,但最后这个问题还是没有解决。已经过去8年了。

不过,幸运的是有解决办法。我在这里找到了。你需要使用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))
    )
)

有时候你可能想用bulk_update,而不是普通的update

有趣的是,bulk_update的实现依赖于和我上面提到的解决办法一样的Case/When/Then/Value的处理方式。

0

其实,这个方法对我来说没用。

但是,下面这个方法有效:

Entry.objects.all().update(value=(F('value')==False))

6

请查看这份文档

Entry.objects.all().update(value= not F('value'))

撰写回答