Django Migrations: A Primer

- 7 mins

Migrations in Django are a way of propagating changes made in the model into the database schema.

Official Django docs summarizes Migration as

Migrations are Django’s way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema

Migrations were introduced as a built-in functionality in Django version 1.7. Migrations are created manually by running certain commands but they automate the task of applying changes to the database. We can create migration for any changes in model, like

Automatically generated migrations are used to apply changes to the database schema. To apply changes in data, one needs to manually write the data migrations.

Let’s consider an example of a Library system and walk through the whole example of creating and applying migrations. Consider that our project is django_library and there is an app called library in it. We are right now focussing only on the Book model.

How to create migrations

To create the migration, Django provides a management command called makemigrations. It can be run as

Here name_of_app is optional.

Consider our library app, migrations for it can be created by running the following command.

A file called will be created in library/migrations directory.

Since this is the first migration for an app, Django names it as initial migration.

For every other migration, Django names it using date and time like

It is always advised to create a named migration since it becomes easier to infer just by looking at the name of what the migration is about.

We can create named migration by running the following command

A small note here, the name of migration should not exceed 50 characters.

Let’s add another field named publisher in our Book model. Our model will now look like

To create named migration for this, we need to run makemigrations as

How to apply a migrations

Once the migration, we need to apply them, so that changes can be reflected in the databases as well.

To apply migration, we need to run migrate command as follows

By running this command, all the unapplied migration are applied to the database.

In our case for Book model, both 0001_initial and 0002_add_publisher will be applied.

Whenever any migration is applied, Django records this in a table called django_migrations.

How to undo migrations

Many times, we need to undo the migration as well. Or in simple words, we need to undo the changes which are done to the database schema by undoing that migration

Undoing a migration can be done by using migrate command, but we need to pass app name as well as the name of migration at which we want to rollback.

Let’s remove publisher field from our Book model. This can be done by undoing 0002_add_publisher migration. Since we need to undo this migration, we will pass 0001_initial as an argument to migrate. The command will look like

By running this command, publisher field will be removed from book table in the database schema.

How to fake migrations

Many times, We just need to run the migration without actually changing the database schema. It happens when we have taken a dump from our staging or production database. To deal with such cases, Django provides a way called fake migration, which applies the migration but does not affect the database schema.

In simpler words, for each migration which is faked, an entry is created in django_migrations table but no changes are done in the database schema.

How to clear migration for an app

Django provides with a built-in functionality, which allows us to clear all the migration for a particular app. To clear migration for an app, we need to run the following command

Here zero tells migrate command to clear the migration for a particular app.

How to list all migrations

Django provides a built-in command called showmigrations to list and display all migrations. It can be run as

When this command is run for our django_library application, we get the following output.

Here [X] indicates that the migration has been applied and [] indicates that the migration has not been applied. In our case, 0002_add_publisher is not applied.


The basic process of creating and applying migration is the following.

Role of django_migrations table

Whenever any migration is applied or unapplied, Django records this in a table called django_migrations. This table stores the name of the app, name and of migration and a datetime field, which tells when the migration was applied.

This table is used by Django to keep track of which migration to apply and which migrations have been applied.

A very likely doubt that arises is no changes are reflected in the database schema when a migration file is manually changed and applied again. This happens because Django has already created an entry for it in django_migrations table. One way to deal with this situation can be deleting the concerned row and then running the migrations again(this is not the official way, but it works).

What is a migration file?

Whenever makemigrations is run, a python file is created. This file contains a class called Migration which contains two attributes

This is an important attribute, which tells that this migration depends on the previous one. It actually allows the migration to be applied in a linear fashion.

This is an array, which contains all the changes that need to be applied to the database schema.

One important thing to note here is that this migration file needs to be added to the Version Control System(git) as well.

Practical Use Cases



Django provides a built-in functionality of propagating changes made in the model to the database schema. Migrations first need to be created using makemigrations. Once created, migrations can be applied by running migrate command. Creating a migration and applying a migration both are two different processes. Automatically generated migrations are used to apply changes only to the database schema. Migrations for data needs to be manually written and applied.

Taranjeet Singh

Taranjeet Singh

Full Stack Developer, Entrepreneur

comments powered by Disqus
rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora