How is a rollback with South supposed to work?
Color me confused. Let's assume we've got a Django project with South migrations. Currently, production project version is A
, version in development B
. Now let's suppose version B
is installed into production:
- Install new code
- Run
./manage.py syncdb && ./manage.py migrate
- Restart web-server and be happy.
Next assumption: version B
doesn't work at all. It did in development, but doesn't in production, so it has to be rolled back. And this is where I must be missing something. I see two possibilities:
- Old code in reinstalled. Now, a South back-migration would be appropriate, however, this is not possible, sin开发者_JAVA技巧ce the old code doesn't contain all the newest migrations needed to go back.
- We first roll-back database changes and then reinstall the old code. However, how do we know which migration is the latest for version
A
? Since one project could easily count a couple dozen apps, you'd need to figure out for each of them which migration stand belongs to the old version, then migrate each app separately and then rollback the code and hope for the best.
In both cases, I'm missing crucial information, either migration code in the first case or "migration <->
version" relationship in the second. What am I missing here?
PS: Yes, I know I can restore the database from backup, this is what I actually do. I want to know how this whole database migration theory fits with rollbacks.
OK. I presume you are working with version control?? That is pretty much crucial at this point to determine what makes up 'A' and 'B'. If we're hand-waving/guessing that this amorpheous blob of code we are referencing is 'A', and this other vaguely defined thing we all label as 'B' - it isn't going to work.
If you are trying to reinstall 'A' in the place of 'B' you have two options: 1) checkout and rebuild 'A' from scratch (sync and migrate) 2) roll 'B' back to 'A'.
1) Likely won't work because you can't afford to kill the data in DB to sync it from nothing
2) Involves migrations. First, you should find the migrations in 'B' and not in 'A'. In south all the migrations for each app are numbered (0001, 0002, 0003, etc). So let's say 'B' is at 050, and 'A' is at 0031. While you have 'B' checked out, run python manage.py migrate appname 0031
That will undo all the DB changes you made for 'B'. Then in your version control system you checkout 'A' (whether 'A' is just a commit or a tag or a branch)
Unfortunately you can't rollback to 'A' and then say "unmigrate everything you don't have". That would be an easier solution - but then you'd need you migration system to know about your version control system, and that is a bit hairy.
Not sure if this was an option in your case but couldn't you have run the backwards migration in production before you moved your code back to version 'A'? This way your db gets back to whichever migration was there before you did your syncdb and then you change your code back to version A and you're right back to where you started.
精彩评论