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 a migration for any changes in the model, like
Add a new model.
Add a particular field in a model
Update field attributes in a model
Delete a field in a model
Rename a field in a model
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 0001_initial.py
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 0007_auto-20180208_1613.py
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.
Workflow
The basic process of creating and applying migration is the following.
First, make changes to the model. This can be adding a new model or updating/removing any fields from the model.
Create migrations by running
makemigrations
.Apply migration by running
migrate
.
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
- dependencies
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.
- operations
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
Migrations gives us the flexibility of propagating database related changes easily across a team. Migration created by a developer can be added to VCS, which later can be applied by another dev, simply by running the
migrate
command.Another way of using migration can be to apply changes in the development environment and fake migrations on the production environment. This is especially helpful in a large organization, where the database is managed specifically by Database Administrators.
Advantages
Migration gives us the flexibility to track database changes in a version control system. This way it becomes easier for us to see how the database changed over a period of time.
Migration offloads the process of manually applying a set of changes to the database. More than one migration can be applied at once by simply running the
migrate
command.
Summary
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.
Top comments (0)