Django AddField default value locking during zero-downtime deploy
0 reputation · 05 Dec 2024, 09:38 UTC
Django AddField default value locking during zero-downtime deploy
Goal: add a non-nullable field with a database default to an existing table in a small Django application while keeping reads and writes available during a staggered deploy across PostgreSQL and MySQL.
Django applies migrations sequentially and wraps schema changes in a transaction on backends that support transactional DDL, such as PostgreSQL and SQLite. Adding a non-nullable column with a default can require a full table rewrite and an exclusive lock on older PostgreSQL versions or MySQL, which blocks concurrent traffic. A RunPython backfill inside the same migration may extend that lock duration. Django does not automatically detect or prevent these unsafe operations.
Assumptions: PostgreSQL 11 or later avoids a rewrite for a constant default, while earlier PostgreSQL and MySQL versions may lock the table. The exact lock behavior depends on the production backend version and must be confirmed before deploy.
Questions: Does Django hold the schema lock for the entire RunPython backfill on PostgreSQL 15? Can MySQL 8.0 add a non-nullable column with a constant default without rewriting the table? Should the field be introduced as nullable, backfilled separately, and then constrained to preserve zero-downtime deploys?