SkillByAIOpen interactive version →

Lesson 13 / 26

Reading the SQL Behind a Migration

Know what will run.

sqlmigrate shows the statements

python manage.py sqlmigrate app 0001 prints the SQL a migration will execute for your database backend, without running it. Check it for large tables: adding indexes or NOT NULL columns can lock tables for a long time. On PostgreSQL, Django offers operations such as AddIndexConcurrently for zero-downtime index creation.

The SQL for the initial migration, run

I ran this with Django 6.1.1 and Python 3.12 in a demo project (shopsite with a catalog app) using SQLite. SQLite statements create both tables with a unique category name, a foreign key, the index Django adds for the foreign key, and the composite index from Meta.

python manage.py sqlmigrate catalog 0001

Output:

BEGIN;
--
-- Create model Category
--
CREATE TABLE "catalog_category" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(50) NOT NULL UNIQUE);
--
-- Create model Product
--
CREATE TABLE "catalog_product" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL, "price" decimal NOT NULL, "in_stock" bool NOT NULL, "created" datetime NOT NULL, "category_id" bigint NOT NULL REFERENCES "catalog_category" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "catalog_product_category_id_35bf920b" ON "catalog_product" ("category_id");
CREATE INDEX "catalog_pro_categor_5a4a66_idx" ON "catalog_product" ("category_id", "price");
COMMIT;

Run sqlmigrate on large-table changes

Reviewing the generated SQL is the cheapest way to spot a migration that would lock production.

Quick check: What does sqlmigrate do?

  • Applies all migrations
  • Prints the SQL for a migration without running it
  • Deletes migrations
  • Creates a superuser
Answer

Prints the SQL for a migration without running it — Inspect before applying.