How to Bulk Update in Django
In Django, by default, every model has an objects
manager. This manager can do many things such as fetch model instances, filter model instances, delete model instances. We can even create our own manager by inheriting the base manager provided by Django.
Now, every single query that we apply, such as retrieving a single model instance using the get()
function or filtering instances using the filter()
method, hits the database once. This means that if we have five get()
statements as follows, the database will be queried five times individually.
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)
This is an inefficient approach because we are hitting the database individually for a single task. If we have to query many instances or update many instances for some models, this approach can slow down our application dramatically.
To solve this problem, Django has an in-built function that can be used to update multiple instances in one query, generally.
bulk_update()
Method in Django
The bulk_update
method has three parameters, namely, objs
, fields
, and batch_size
.
objs
- A list of operations to be performedfields
- A list of fields on which the queries have to be performedbatch_size
- The number of objects to be saved in a single database query. It is an optional argument. By default, all the objects are updated and saved.
Consider an example. Suppose we have a Person
model, and we have to increment the age of all the persons by 1
using the bulk_update()
method. We would do the following.
In 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)
In views.py
:
people = Person.objects.all()
for person in people:
person.age += 1
Person.objects.bulk_update(people, update_fields=["age"])
This operation will update the age of all the persons in a single query which is very efficient.
Drawbacks of the bulk_update()
Method
The bulk_update()
method is excellent, but not all the glitter is gold. This method has a few drawbacks.
- Using the
bulk_update()
method, we can’t update the primary keys of instances. - Every model has a
save()
method. This method is not called when using thebulk_update()
method. - We have to mention a batch size if we are updating many columns for a lot of records. Otherwise, the generated SQL query will be very long.