【发布时间】:2022-10-24 08:43:15
【问题描述】:
我有一个包含大约 10,000 多行数据的 5 列模型。现在我想根据其他列值更新所有行中的一列。
【问题讨论】:
标签: django
我有一个包含大约 10,000 多行数据的 5 列模型。现在我想根据其他列值更新所有行中的一列。
【问题讨论】:
标签: django
我认为,对于您的情况“我想根据其他列值更新所有行中的一列。”,最好的选择是使用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
【讨论】:
进行批量更新的开箱即用的 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 来避免这种情况。
- 更新在多表继承祖先上定义的字段将导致每个祖先的额外查询。
- 当单个批次包含重复项时,只有该批次中的第一个实例会导致更新。
【讨论】:
我有同样的要求,所以我创建了这个repr:
【讨论】: