Bulk Update in Django

  1. bulk_update() Method in Django
  2. Drawbacks of the bulk_update() Method

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.

  1. objs - A list of operations to be performed
  2. fields - A list of fields on which the queries have to be performed
  3. batch_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 the bulk_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.
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.