Django cookbook · Advanced

Add a required column without downtime

Adding a NOT NULL column (or renaming one) locks the table or breaks the running version during deploys.

Create a free account to save this page, take notes and track your progress. Sign in

Approach

Split the change across deploys so old and new code both work: add the column as nullable (or with a database default), backfill, then make it required. For renames, add the new column, write both, switch reads, then drop.

Solution

# Deploy 1: add the column with a database-level default (no table rewrite on PostgreSQL 11+)
from django.db import migrations, models


class Migration(migrations.Migration):
    dependencies = [("shop", "0020_previous")]
    operations = [
        migrations.AddField(
            model_name="order",
            name="currency",
            field=models.CharField(max_length=3, db_default="USD"),
        ),
    ]


# Deploy 2 (after backfilling any special cases): add an index without locking writes
from django.contrib.postgres.operations import AddIndexConcurrently


class Migration(migrations.Migration):
    atomic = False                                       # CONCURRENTLY can't run in a transaction
    dependencies = [("shop", "0021_order_currency")]
    operations = [
        AddIndexConcurrently("order", models.Index(fields=["currency", "created_at"], name="order_currency_idx")),
    ]

Pitfalls

  • Renaming a column in one step while the old code (still running during the deploy) uses the old name.
  • Creating indexes on large tables without CONCURRENTLY, blocking writes.
  • Removing a field from the model and the database in the same deploy; remove it from code first.

Variations

  • Use SeparateDatabaseAndState to change Django's view of a field without touching the database.
  • Tools like django-pg-zero-downtime-migrations add checks for unsafe operations.

Further reading: Field.db_default

Reference: https://docs.djangoproject.com/en/6.0/ref/models/fields/#db-default

More Django recipes

Was this page helpful?