Posts tagged "migrations"

A Post Entitled New in Rails 2.1: Timestamped migrations

posted 4 years ago in rails migrations

What was wrong with migrations?

If you’ve been part of any development team that was larger than the “Army of One” you’ve probably run into an issue with migrations. It’s happened to me a few times: one member of the teams goes head-down on some problem and it takes longer than expected. Not wanting to check in ‘broken” code the patch builds up for a while… and so do the migrations to fix db issues. Finally ready, the change gets checked in and … poof… What worked no longer works. Why?

While Mr. Fix-It was head down the trunk was updated with other migrations. But these migrations had overlapping numbers so when they merged into the code base it was unpredictable which ones would be run on any given system. To be clear, the migrations will be run in a very definitie order. They’re run in alphanumeric order, but only one migration of a specific ‘version’ will be executed. As a result, which migrations are run on your system depends on how many you’d already checked out and run and the alphabetical naming of each script. Now it’s up to you and your team to rename all the migrations, backing them out one by one and adding them back to make sure all the database changes are applied appropriately. Yikes!

Enter Sandman

Disclaimer: I’ve only heard ‘Sandman’ when certain closers enter baseball games but I thought someone would appreciate the reference

The new timestamped migrations may put all these issues to rest. Instead of prefixing the migrations with 001, 002, 003, etc the prefix will now be a timestamp. So, the result of running a ‘script/generate scaffod MyObject attribute1:string attribute2:integer’ will be a file with a name like 20080601214508_create_my_object. The likelihood that you and a teammate create a migration at the exact same time is pretty small so the ‘level collisions’ are almost surely a thing of the past.

Tracking revisions, not the version

Even better, though, is that the schema_info table will now track revisions, not only the latest version. That is, every migration that is run via rake db:migrate will be recorded in the database. As a result, whenever Mr. Fix-It decides to enlighten the rest of the team with his update, a rake db:migrate will be able to identify the individual migrations that have not been run whether they were on Mr. Fix-It’s machine (when he finally updates from trunk/master) or on a teammates’ machine (when the patch is loaded).

Even better, there are new rake db:migrate:up and rake db:migrate:down commands. These commands accept an individual migration ‘version’ (the time stamp) and either run it (up) or back it out (down). Remember that table that you created and decided you’d overengineered? Now it’s a lot easier to back that one out.

Could it get even better?

Yes, it could get better. Those of you who’ve read The Rails Way (Obie Fernandez, Addison-Wesley Professional Series, 2007) may have come across a recommendation to accumulate migration changes until they are pushed to production. That is, rather than create three migrations for a table and some additional fields while the table is in development, there is a recommendation to have one create script that gets updated until it’s pushed to production. I’ve tried this on a couple of apps and really liked the approach because it cuts down on the ‘noise’ in the migration collections. I’m willing to accept the argument that migrations are not really necessary for tracking database changes until they change something beyond development.

What could be even better that the current implementation of the timestamped migration would be if it could detect these changes in the migration files. It should be possible to check the creation and update times of the files to see if they’ve been updated and then validate the updated time in the migrations db. This particular idea has some drawbacks, particularly if a production migration were ever touched accidentally.

Comments

About this site and its Author


The Tumblrs to Follow

  • cdmwebs
  • staff
  • paulsullivanjr
  • dawnvanasse
  • bitbltr