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:
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.
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 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: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
$ rake db:create
$ rake db:schema:load
$ rake db:seed # see link above for Rake task definition for this
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.
Leave a Reply