【问题标题】:Best way to bulk update query with dynamic values conditionally in Django在 Django 中有条件地使用动态值批量更新查询的最佳方法
【发布时间】:2018-06-25 19:12:45
【问题描述】:

我只是想知道是否可以在 django 中批量保存查询。

例如,通常我必须遍历每个对象

for obj in queryset:
    if condition:
        obj.field = True
        obj.save()

编辑:

我知道上面的情况可以用update方法处理。但是,上面的示例将所有fields 保存为相同的value。如果有不同的条件呢?

for obj in queryset:
    if condition:
        obj.field = True
        obj.save()
    else:
        obj.field = False
        obj.save()

以上可能不是我目前能想到的最好的示例,但我会说类似的东西。

会有更快的方法吗?

提前感谢您的任何建议

【问题讨论】:

  • 我编辑了标题,希望这样可以使所问的问题更加明显。通过提问者提供的附加说明,这毕竟可能不是重复的。

标签: python django save django-queryset


【解决方案1】:

查询集有一个update 方法可以做到这一点。但是,有一些注意事项,例如未调用模型 save 方法。如果您为模型覆盖并实现自己的 save 方法,请记住这一点。

来自 django 文档:

例如,要为 2010 年发布的所有博客条目关闭 cmets,您可以这样做:

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)

所以,换句话说queryset.update(field='value')

更新:关于根据条件动态执行此操作...

因为update 在 SQL 级别执行(由 DB 执行),您可能希望在您的查询中处理您的条件,这几乎总是可以通过一种或另一种方式实现。您可以进行多次查询以获得效果。

def my_bulk_update():
    MyModel.objects.filter(conditional_field=True).update(field=True)
    MyModel.objects.filter(conditional_field=False).update(field=False)

您可以通过许多巧妙的方式进行查询来完成此操作,(包括annotating, aggregatingexpressions 等)...您可能会惊讶于您可以在查询中填充多少逻辑。请务必查看making queries 上的文档。当然,你也可以编写自己的 SQL 来有效地做同样的事情,如果 ORM 不能很好地生成查询。

如果逻辑真的很复杂,不能用 SQL 来做,你可以按照你已经写过的粗略做,但如果你有大量记录,可能需要使用transactions 来提高性能。

【讨论】:

  • 对不起 >.update 但是此更新将更新所有具有相同值的查询集。如果该值是每个查询集根据条件而有所不同?(让我更新我的问题,对此感到抱歉)
  • @Dora 啊,我想我现在明白你的意思了。好吧,简而言之,您可能希望在查询中使用 if condition 逻辑。有很多聪明的方法可以做到这一点。我会在一秒钟内更新我的答案,一旦我更新了,如果您需要更多说明,请告诉我。
  • @Dora 我更新了我的答案。如果您有一些特定的逻辑,您对如何将您想到的一些特定的基本逻辑应用于查询感到好奇,请告诉我,我会看看我是否可以在我的答案中提供帮助。如果逻辑足够复杂,请研究有关进行查询的文档,或者如果您无法弄清楚,请专门为此提出另一个问题。有可能可以通过查询来完成。
  • 感谢您帮助我获得标题,我真的不擅长给出标题并看到您的 conditional_field 我确实了解更多,即使仍然有一个小问题留在我的脑海中,我不能'不要把它弄出来。我遇到了一些事情,但我会给出一个正确的答案,因为这两个例子就是我现在脑子里的东西。非常感谢您花时间解释。
【解决方案2】:

如果需要为数据库中的每条记录设置不同的值,可以手动提交。

from django.db import transaction    
...
transaction.set_autocommit(False)
for obj in queryset:
if condition:
    obj.field = random_value
    obj.save()
else:
    obj.field = another_random_value
    obj.save()
transaction.commit()
transaction.set_autocommit(True)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2012-05-25
    • 2017-11-28
    • 1970-01-01
    • 2015-06-15
    • 2019-07-04
    • 2020-08-22
    相关资源
    最近更新 更多