Database Migrations are an interesting piece of the Django community. Rails has the functionality built in, but Django currently relies on third party apps for this functionality. One of the core philosophies about not including apps in the Django core is that ideas percolate better in the fast release environment outside of the core. When something goes into core, it is automatically seen as blessed, and will certainly become the defacto answer to a problem. Leaving things outside allows multiple different implementations to develop (as they did), and for one to become the standard (which it has). Along the way it has picked up ideas from others, and now provides a good answer to migrations.

I have talked about south in the past, using it to migrate test fixtures . This serves as a basic tutorial and introduction into south as well.

South has emerged as the obvious choice for database migrations in the Django community. We use it in production at work at the Journal World, and it has served us well.

Main Features¶

Automatic Migrations¶ Most of the migrations that I write, I don’t write a single line of code. South has the ability to how you model looked at the end of your last migration, and then extrapolate what has changed (in most simple and modestly complex cases). There are obviously times that it falls down, but for simple addition, deletion, and modification of fields it has worked almost flawlessly for me. With a simple command, it will do all your work for you. django - admin . py migrate app_name -- auto It has problems with Generic Foreign Keys and a couple of other more complex models. However, I would say that it absolutely nails the 80% case that most migrations fall in to.

Fake ORM (“ORM Freezing”)¶ This is a feature that South has grown from it’s Migratory roots. I think it is one of the best conceptual features for migrations. It allows you to use a Fake ORM (the real ORM, applied to the aforementioned fake models), to do data transformation in your migrations. This example from the tutorial shows the value: def forwards ( self , orm ): for adopter in orm . Adopter . objects . all (): try : adopter . first_name , adopter . last_name = adopter . name . split ( " " , 1 ) except ValueError : adopter . first_name , adopter . last_name = adopter . name , "" adopter . save ()

Database Independent¶ This sounds like an obvious feature, but a lot of the approaches for migrations were only viable on one database. The support for SQLite is still lacking, but that is because of fundamental limitations in the way SQLite works. Most people using SQLite can just wipe their database and start over, if not, you should probably be using another database.

It knows when you’ve been naughty¶ South keeps track of all the migrations that you have run, and it intelligently informs you if you have missed a migration. It also supports inter-dependencies on migrations. This allows you to be safe in your knowledge that your migrations will be run properly, and that state is maintained. This sounds like a hand-wavey feature, but when you’re migrating your data, knowing when things aren’t quite right is a nice feeling! South also keeps track of the migrations that are on disk, and won’t let you migrate if they are different than previous runs. This makes sure that you aren’t running against a different version of the code; allowing you to be sure that the migrations being run are correct.