Django Bulk Update

2.2.0 · active · verified Wed Apr 15

django-bulk-update is a Django library that enables efficient bulk updates of multiple model instances using a single database query. It significantly improves performance compared to iterating and calling `save()` on each object individually. The current version is 2.2.0, and the project maintains an active but not rapid release cadence, ensuring compatibility with recent Django versions.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to integrate `BulkUpdateManager` into a Django model, create initial instances using `bulk_create`, modify these instances in memory, and then efficiently persist changes to specific fields across all modified objects using a single `bulk_update` query. It includes a complete, runnable standalone Django setup with an in-memory SQLite database.

import os
import django
from django.conf import settings
from django.db import models
from django_bulk_update.manager import BulkUpdateManager

# --- Minimal Django setup for a runnable standalone script ---
# Configure settings for an in-memory SQLite database
if not settings.configured:
    settings.configure(
        DEBUG=True,
        INSTALLED_APPS=[
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'myapp' # Dummy app for model definition
        ],
        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}}
    )
django.setup()

# Define a simple Django model
class MyModel(models.Model):
    name = models.CharField(max_length=255)
    age = models.IntegerField()

    objects = BulkUpdateManager() # Use the custom manager

    class Meta:
        app_label = 'myapp' # Required for standalone scripts without full project structure

    def __str__(self):
        return f"MyModel(id={self.id}, name='{self.name}', age={self.age})"

# --- Create and apply migrations for the in-memory database ---
# This mimics `python manage.py makemigrations myapp` and `python manage.py migrate myapp`
from django.core.management import call_command
from io import StringIO

# Redirect output to prevent verbose console output from migrations
stdout_redirect = StringIO()
stderr_redirect = StringIO()

try:
    # Make migrations for 'myapp'
    call_command('makemigrations', 'myapp', interactive=False, stdout=stdout_redirect, stderr=stderr_redirect)
    # Apply migrations
    call_command('migrate', 'myapp', interactive=False, stdout=stdout_redirect, stderr=stderr_redirect)
except Exception as e:
    print(f"Error setting up database: {e}")
    print(f"Stdout: {stdout_redirect.getvalue()}")
    print(f"Stderr: {stderr_redirect.getvalue()}")
    exit(1)

print("Database and model schema initialized successfully.\n")

# --- Quickstart core functionality ---
print("Creating objects with bulk_create...")
objs_to_create = [MyModel(name=f"User {i}", age=i) for i in range(5)]
MyModel.objects.bulk_create(objs_to_create)

# Retrieve them to ensure IDs are set and to have fresh instances
objs = list(MyModel.objects.all().order_by('id'))
print("Original objects:")
for obj in objs:
    print(obj)

print("\nModifying objects in memory...")
for obj in objs:
    obj.age += 10 # Increment age
    obj.name = f"Updated {obj.name} (v2)" # Change name

# Perform the bulk update for specific fields
# Only 'name' and 'age' fields will be included in the UPDATE query
MyModel.objects.bulk_update(objs, update_fields=['name', 'age'])

print("\nObjects after bulk_update (fetched from DB):")
for obj in MyModel.objects.all().order_by('id'):
    print(obj)

view raw JSON →