Database Migrations with Django

Josh Dwernychuk
Sightwave Software
Published in
2 min readNov 22, 2017

Migrations can be tricky with Django and can get hairy when not navigated precisely.

Django offers four management commands related to migrations:

  • makemigrations — used to make migration files from current data models
  • migrate — used to migrate migration files to the configured database
  • showmigrations — used to show migrations that have and have not been run on the database
  • squashmigrations — used to squash multiple migration files into a single migration file

Let’s say we’ve adjusted our data models and it is time to make a migration file and migrate the newly adjusted models to the database.

We might try something like this:

./manage.py makemigrations
./manage.py migrate

However, if we are only intending to make migrations for a specific app within our django project, or only intending to run migrations for a specific app within our project, then we can run the previous commands with an app_name argument like so:

./manage.py makemigrations app
./manage.py migrate app

It might be the case that we would like to revert the database back to a previous migration after we have already run our migrations, in this case we can add an extra argument to rollback to the specific migration for a specific app like so:

./manage.py migrate app migration_file_name

In practice, this may look something like this:

./manage.py migrate app 0002_auto_20170808_2327

We can rollback all migrations for a specific app with the “zero” argument like so:

./manage.py migrate app zero

Keeping track of the migrations that have been run for all of the apps within a django project can be tough; thankfully, django offers the showmigrations command to allow developers to view the migrations that have and have not been run.

./manage.py showmigrations appapp
[X] 0001_initial
[X] 0002_auto_20170831_2151
[X] 0003_auto_20170831_2247
[X] 0004_auto_20170901_2016
[ ] 0005_auto_20170901_2116

This tells us that migrations 0001_initial through 0004_auto_20170901_2016 have been migrated, and that migration 0005_auto_20170901_2116 has not been migrated and is still just a migration file in the application’s migrations directory.

It’s possible that multiple migrations will be made while building out a feature; we can squash these migrations before pushing to source control like so:

./manage.py squashmigrations app earliest_migrations_file_name latest_migrations_file_name

The command above will squash all migrations between earliest_migrations_file_name and latest_migrations_file_name into a single migrations file. If we want to squash up migrations from the initial migration including and prior to a single file, we can drop the latest_migrations_file_name argument and use:

./manage.py squashmigrations app earliest_migrations_file_name

This will squash all migrations between and including the initial migration and the named earliest_migrations_file_name.

Good luck with Django migrations!

--

--

Josh Dwernychuk
Sightwave Software

Sightwave Software delivers high-quality software solutions for online marketing agencies