【问题标题】:Bulk update of a model field based on a condition of the other model fields根据其他模型字段的条件批量更新模型字段
【发布时间】:2022-10-24 08:43:15
【问题描述】:

我有一个包含大约 10,000 多行数据的 5 列模型。现在我想根据其他列值更新所有行中的一列。

【问题讨论】:

    标签: django


    【解决方案1】:

    我认为,对于您的情况“我想根据其他列值更新所有行中的一列。”,最好的选择是使用Conditional update

    让我们假设这个模型:

    class Person(models.Model):
        f1 = models.IntegerField()
        f2 = models.IntegerField()
        f3 = models.IntegerField()
        f4 = models.IntegerField()
    

    您可以通过以下方式更新它:

    rom django.db.models import F, When, Case
    
    new_value = Case(
        When(f1__gte=F('f2'), then=F('f1')),
        default=F('f2') 
    )
    
    Person.objects.update(f3=new_value)
    

    这引发了一个简单的更新 sql 语句:

    >>> import logging
    >>> l = logging.getLogger('django.db.backends')
    >>> l.setLevel(logging.DEBUG)
    >>> l.addHandler(logging.StreamHandler())
    >>> Person.objects.update(f3=c)
    (0.000) UPDATE "tt_person" SET "f3" = CASE WHEN ("tt_person"."f1" >= "tt_person"."f2") THEN "tt_person"."f1" ELSE "tt_person"."f2" END; args=()
    0
    

    【讨论】:

      【解决方案2】:

      进行批量更新的开箱即用的 django 功能是 bulk_update()。这里有一个例子:

      myModel = MyModel.objects.all()
      
      for l in myModel:
          if c1=='ChkVal1' and c2 < c3:    
              c4='Value 1'
          elif c1=='ChkVal2' and c2 b> c3:
              c4='Value 2'
          else
              c4='Value 3'
      
      MyModel.objects.bulk_update(myModel, update_fields = ['c4'])
      

      请记住,引用文档:

      • 您无法更新模型的主键。
      • 不调用每个模型的 save() 方法,也不发送 pre_save 和 post_save 信号。
      • 如果更新大量行中的大量列,生成的 SQL 可能会非常大。通过指定合适的 batch_size 来避免这种情况。
      • 更新在多表继承祖先上定义的字段将导致每个祖先的额外查询。
      • 当单个批次包含重复项时,只有该批次中的第一个实例会导致更新。

      【讨论】:

      • 如果您需要从其他模型或外部源中选择数据,这是复杂列转换的绝佳解决方案。因为这个,我完全支持你的答案。,要从其他列值的计算组合中更新一列,你有没有更有效的方法来做到这一点:stackoverflow.com/a/70181590/842935
      【解决方案3】:

      我有同样的要求,所以我创建了这个repr:

      https://github.com/954-Ivory/django_bulk_hook_manager

      【讨论】:

        猜你喜欢
        • 2016-06-10
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 1970-01-01
        • 2012-05-11
        • 1970-01-01
        • 2013-07-19
        • 1970-01-01
        相关资源
        最近更新 更多