What happens when a migration fails
So… you’re writing a migration, you think you’ve got it right - time to try it out. You run
rake db:migrate
to apply your migration, and it doesn’t work.
Your database has some of the changes from the migration in it, and the rest aren’t there. How do you get it back into the state it was in before you attempted the migration?
You might think that
rake db:migrate VERSION=nn
(where nn is the migration number before the one that failed)
would do the job, presuming that your failed migration’s self.down method runs the statements to rollback your changes in the same order as the self.up method makes the changes.
Unfortunately, nothing happens. Rails knows it didn’t complete the migration, so has left the current schema version number as at the end of the last migration which did complete.
At this point, you are faced with opening up your database and reverting the changes that did get made manually…
There is, however, a patch in rails-trac to fix this issue - if you are using a database that supports transactions round data definition statements (such as Postgres). Once installed, your migration is wrapped in a transaction, which is rolled back if any errors occur. Yippee!
August 26th, 2007 at 12:15 am
This is probably the most annoyng migration behaviour along with add_column not… reloading columns.
August 28th, 2007 at 12:30 pm
@ynw:
Actually, it appears that add_column … does reload column information - when you’re using the development environment. It doesn’t do this in the production environment, though, and if you try to update your new columns using Model.update_attributes you don’t get any messages anywhere to tell you that nothing’s been updated. It all appears to have worked fine.
Personally, I think this behaviour’s even worse than the original - when you develop the migration, it all works, and when you run it in production, it appears to have worked, but hasn’t actually worked!