Hi, I am Amit Mathur. Welcome to my blog. I write mostly about my experiences with Software development, Web apps, Rails, and occasionally some personal stuff.

Rails migrations revisited

March 24th, 2009

Rails Database migrations is a great piece of technology and deservedly popular. However, there are aspects of it which are not quite well understood. Here I discuss couple of such points: how to manage the schema.rb file and how to handle data migrations.



No, we are not back to 2007 again. There are just a few things about migrations that I think some people have still not got right. So, I thought I will highlight them here.

Rails have had migrations for quite a few releases now. Here’s a brief review:

Recap

When you want to do a change in your database schema, like add a column or change a table definition, you generate a migration, populate the code for forward and backward migrations, and run rake db:migrate. It let’s you change your DB incrementally. Everybody gets this part I think. See Rails guides for a wonderful overview.

schema.rb file

Running a migration updates the db/schema.rb file. It is required to put this in your source control and check it in with the migration. A lot of people actively ignore this file (by using svn:ignore or .gitignore). Don’t.

Migrations are useful when you are upgrading your database. Where as if you are setting up a new instance of the database (say a new user joins your team or you are setting up a new staging server), you should not be running the migrations. Instead do this:

  $ rake db:create
  $ rake db:schema:load

Running a long winded migrations, in most non trivial projects, is almost bound to fail (because of name changes in your source code, since you are not going back and updating your migrations). This is official Rails policy (see the comment on top of your db/schema.rb or DHH’s code commit here)

See here for a summary of the opposite view.

Data migrations

Data migration is porting the data in the tables to the new schema. Unfortunately, Rails does not have a clearly specified way of dealing with this. Usually developers do not treat this as a separate issue but handle it as part of usual Rails migrations.

There are two cases when you may find yourself dealing with data in migrations:
  • while seeding the database with some data, or
  • porting the data in older tables to newer schema.

Most of the times it is possible to handle both using migrations. However, for the second case, you may sometimes need to create special migration scripts.

However, if you are not running migrations to start a new database, you still need a way to seed the database with the required data. Here is something I have used which has worked well for several projects which I picked up from here

  • In addition to creating a migration, put seed data in db/fixtures/*.yml
  • load the seed data from db/fixtures when initializing a new database


$ rake db:create
$ rake db:schema:load
$ rake db:seed # see link above for Rake task definition for this


conclusion

Most projects ignore data migrations during development, which is not entirely wrong. Who cares for lost data during development? But, you will need a robust strategy for handling data migrations once you are on production and you should prepare yourself with a methodology well in advance. And a last final tip, backup your production database before running any migrations.



Bookmark and Share

Leave a Reply

If you can read this, you don't use a typical Web Browser that plays nice with CSS.
Please do not fill in anything here!

(Textile formatting is supported)

call
Web Statistics