What’s new in Django 1.7? Basically migrations. While there are some other nice features, the new migrations system is the big one.
In the past you probably used South to handle database changes. However, in Django 1.7, migrations are now integrated into the Django Core thanks to Andrew Godwin, who ran this Kickstarter. He is also the original creator of South.
In honor of this momentous update, we are going to cover migrations, how they work and how to get the most out of them across three blog posts and one video:
- Part 1: Django Migrations – A Primer (current article)
- Part 2: Digging Deeper into Migrations
- Part 3: Data Migrations
- Video: Django 1.7 Migrations – primer
The problems that Migrations Solve
- Speed up the notoriously slow process of changing a database schema.
- Make it easy to use git to track your database schema and its associated changes. Databases simply aren’t aware of git or other version control systems. Git is awesome for code, but not so much for database schemas.
- Provide an easy way to maintain fixture data linked to the appropriate schema.
- Keep the code and schema in sync.
Have you ever had to make a change to an existing table (like re-naming a field) and you didn’t want to mess with dropping the table and re-adding it?
Migrations solve that.
Or perhaps you needed to update the schema on a live application with millions of rows of data that simply cannot be lost.
Migrations make this much easier.
In general, migrations allow you to manage and work with your database schema in the same way you would with your Django code. You can store versions of it in git, you can update it from the command line, and you don’t have to worry about creating large complex SQL queries to keep everything up to date – although you still can if you love pain… I mean SQL.
Getting Started with Migrations
For this blog post we are going to create a simple bitcoin tracker app (actually we are just going to create the model).
Be sure check out the video to see examples of the migrations workflow.
Setup the project
With Django 1.7 installed you can create the project using the following commands:
1 2 3
That should give you a simple project with an app called
historical_data. Now to create a model edit
1 2 3 4 5
Also don’t forget to add the newly created app to
This is a basic model to keep track of bitcoin prices.
Create the migrations
With the model created, the first thing we need to do is “initialize” our migrations. We can do this with the following command:
Note: Specifying the name of the application,
historical_data, is optional. Leaving it off will create migrations for all apps.
Upon running the above command Django migrations will create the migrations for you and output an informational message such as:
1 2 3
This creates the migrations files which instruct Django on how to create the models that you need.
Then to apply the models (e.g., update the database) just run:
Not only will this apply the migrations we just created for
PriceHistory but since this is a new app, it will create all the Django tables for us as well (just like
syncdb did in Django versions prior to 1.7).
So the basic process for using migrations looks like this:
- Create or update a model.
./manage.py makemigrations <app_name>.
./manage.py migrateto migrate everything or
./manage.py migrate <app_name>to migrate an individual app.
- Repeat as necessary.
That’s it! Pretty straight-forward for the basic use-case. Fortunately, this basic use case will work the majority of the time!
Apply Migrations to an Existing Project
That’s all well and good if you’re starting from scratch but many people will be upgrading from a previous version of Django and migrating from South.
To do that, Django recommends to just start using the new migrations system and everything should work. The recommended upgrade path from South to Django 1.7 migrations, paraphrased from here is basically:
- Delete all your South migration files (yup – just blow ‘em away).
./manage.py makemigrations. Django will just make initial migrations files based upon your current models.
./manage.py migrate. Django will see the tables that already exist for your migrations and just mark them as completed without running them.
Now, if you have circular dependencies and are getting errors when going through the above process, you may have to fake the migration with:
Also, if you have a need to support both South and Django Migrations at the same time then upgrade to South 1.0 and read this article.
South vs Django migrations
For those familiar with South this should feel pretty familiar and probably a little bit cleaner. For easy reference the following table compares the old South workflow to the new Django Migrations workflow:
So from the table we can see that Django Migrations, basically follows the same process as South (at least for the standard migration process) – it just simplifies things a bit.
That’s it. It’s all meant to be very straight forward. Of course there will always be edge cases when things don’t work out exactly as intended – but we’ll save that for next time.