DO NOT FOLLOW (was: Best way to clear and reset Django-South migration history)
Posted by Gene at
09:04 on Wed 21 Apr 2010
-- 6 Comments
Stop, There are some flaws in this. I'll fix it up soon and repost. If you understand South and Django, you can probably find the flaws. Beware.
Overview
A programmer using South is able to make rapid changes to the DB schema of a project over a short period of time. When it's time to check-in work, as a programmer, you may want to collapse the migrations you have created into one
Checking in all your migrations isn't a problem, but if you find you prefer to have a clean migration history you can have your programmers follow this procedure.
The steps
- Reset your migration history for the app up to the last checked in migration.
./manage.py migrate appname --fake MIGRATION_NUMBER--fake means don't touch the application's DB. Just remove all migration rows from south_migrationhistory up to that migration number.
- Remove all migration files up to that number
rm appname/migrations/ALL_MIGRATIONS_OLDER_THAN MIGRATION_NUMBER
- Recreate the "next" migration to match your current DB state.
./manage.py schemamigration appname --auto
- Apply the migration to create the DB objects
./manage.py migrate appname
Alternatively, you might want to completely rebuild your DB. In this case, do the following
- In Step 1. Make MIGRATION_NUMBER the string 'zero'
./manage.py migrate appname zeroThis removes all migration history, and the DB. If this fails. You can use --fake, and then remove the DB manually.
- In Step 2, remove all the migrations
rm appname/migrations/*
- In Step 3, do the following instead
./manage.py schemamigration appname --initialThis creates the 0001 migration based on your models.
- Apply the migration to create the initial DB objects
./manage.py migrate appname

@Carl There is one very important reason: testing speed. Right now, I'm having about 60 migrations that need to run before the actual tests can start and this takes a lot of time.
- PassyI changed this post to a form that allows you to collapse the migration history to any point. However, it does require you do it before you have distributed your migrations.
- Gene (response)Hi Carl, It's a bit cleaner to have one migration for a group of migrations when only 1 is necessary. The ease of schema updates going forward during development, can cause quite a lot of migrations to be created in a short period of time. It's my preference to collapse the migrations down at release points.
- GeneWhat's the actual reason for doing this? None is given. Having those earlier migrations around doesn't hurt anything; you run them once on the newly-deployed production system, and you're done. Why not just keep them and avoid extra work? Why the rush to erase history?
If you do what's recommended above, you have to make sure every developer with a development copy of the system also does step 2 and runs the new initial migration with --fake.
- Carl MeyerI'm not aware of any way to collapse a subset of migrations in to one.
I think you could release version 1 with migration 001, and then keep that revision file somewhere other than your migrations/ directory.
Then, if you have to go back to version 1 source, to fix a bug in a live system that is on version 1, for example, you could check out the source and copy the migration for the version 1 release into migrations/ and then migrate 001.
I'm assuming since there's a production system in this example, you could get the data to populate the DB from that system.
I'm sure there other other options here. Anyone care to chime in?
- Gene (response)What about subsequent releases?
The way I understand the instructions - thanks btw! - the reset basically contracts all the development migrations into one, which is used to set up the initial database on the production system.
So as an end result, the production system will have its database set up, and a 0001_initial in its "migrations" directory. So far so good. A clean slate.
Now the developers go back and for the next release, there are another 40 migrations which have been made in the course of the development. It would be nice if they too could be contracted into one (technically otherwise identical) migration.
How could that be achieved?
- Danny AdairDelete all migrations except the first, clear them also from the table south_migrationhistory, and then run schemamigration to create that one big step?