Django 中的批量更新
Vaibhav Vaibhav
2023年1月30日
在 Django 中,默认情况下,每个模型都有一个对象管理器。这个管理器可以做很多事情,比如获取模型实例、过滤模型实例、删除模型实例。我们甚至可以通过继承 Django 提供的基础管理器来创建我们自己的管理器。
现在,我们应用的每个查询,例如使用 get()
函数检索单个模型实例或使用 filter()
方法过滤实例,都会命中数据库一次。这意味着,如果我们有如下 5 个 get()
语句,数据库将被单独查询 5 次。
person = Person.objects.get(id=1)
person = Person.objects.get(id=2)
person = Person.objects.get(id=3)
person = Person.objects.get(id=4)
person = Person.objects.get(id=5)
这是一种低效的方法,因为我们正在为单个任务单独访问数据库。如果我们必须为某些模型查询多个实例或更新多个实例,这种方法会显着降低我们的应用程序的速度。
为了解决这个问题,Django 有一个内置函数,通常可以用于在一个查询中更新多个实例。
bulk_update()
Django 中的方法
bulk_update
方法具有三个参数,即 objs
、fields
和 batch_size
。
objs
- 要执行的操作列表fields
- 必须执行查询的字段列表batch_size
- 要在单个数据库查询中保存的对象数。它是一个可选参数。默认情况下,更新并保存所有对象。
考虑一个例子。假设我们有一个 Person
模型,我们必须使用 bulk_update()
方法将所有人员的年龄增加 1
。我们会做以下事情。
在 models.py
中:
from django.db import models
class Person(models.Model):
username = models.CharField(max_length=200, unique=True)
firstName = models.CharField(max_length=200)
middleName = models.CharField(max_length=200)
lastName = models.CharField(max_length=200)
age = models.IntegerField(default=0)
在 views.py
中:
people = Person.objects.all()
for person in people:
person.age += 1
Person.objects.bulk_update(people, update_fields=["age"])
此操作将在单个查询中更新所有人员的年龄,这是非常有效的。
bulk_update()
方法的缺点
bulk_update()
方法非常好,但并非所有的闪光点都是金子。这种方法有一些缺点。
- 使用
bulk_update()
方法,我们无法更新实例的主键。 - 每个模型都有一个
save()
方法。使用bulk_update()
方法时不会调用此方法。 - 如果我们要为大量记录更新许多列,则必须提及批量大小。否则,生成的 SQL 查询会很长。
作者: Vaibhav Vaibhav