Migrations

Django · Essentials · 10 min

Migrations keep every developer's and server's database schema in sync with the code.

Django never changes your database silently. When models change, you run two commands:

1. python manage.py makemigrations: compares models to the state recorded in existing migration files and writes a new file such as blog/migrations/0002_post_views.py with operations like AddField. 2. python manage.py migrate: applies unapplied migrations to the database and records them in the django_migrations table.

Migration files are code: commit them to version control with the model change, review them, and deploy them together. Every environment then reaches the same schema by running migrate.

Useful commands:

  • showmigrations: which migrations are applied
  • sqlmigrate blog 0002: the SQL a migration will run, which is great for reviewing locking risks
  • migrate blog 0001: migrate backwards to an earlier state (if operations are reversible)
  • makemigrations --check --dry-run: fails in CI if someone changed models without creating migrations

When adding a non-nullable field to a table with rows, makemigrations asks for a one-off default, or you add default= or null=True to the field.

Rules of thumb:

  • never edit a migration that has already been applied elsewhere; create a new one
  • don't delete migration files from a deployed app
  • when two branches both add migrations, makemigrations --merge creates a merge migration

Migrations also capture non-schema changes such as choices, so small model edits create migrations too; that's expected.

Example

# 1. change the model (blog/models.py)
#        views = models.PositiveIntegerField(default=0)

$ python manage.py makemigrations blog
Migrations for 'blog':
  blog/migrations/0002_post_views.py
    + Add field views to post

$ python manage.py sqlmigrate blog 0002          # review the SQL
$ python manage.py migrate
Applying blog.0002_post_views... OK

$ python manage.py showmigrations blog
blog
 [X] 0001_initial
 [X] 0002_post_views

# CI: fail if models and migrations are out of sync
$ python manage.py makemigrations --check --dry-run

Remember

  • makemigrations writes migration files; migrate applies them
  • Commit migrations with the model change
  • Never edit migrations that already ran elsewhere

Watch out for

  • Changing models and forgetting makemigrations, so production lacks the column.

Check yourself

  1. You added a field to a model. What must happen before the database has the new column?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.djangoproject.com/en/6.0/topics/migrations/