courtenay just sent in a new ticket for Rails Core: #6799. To summarize, his patch allows two migrations to have the same number, and migrates them in parallel. courtenay blogged about his patch as simultaneous migrations
I’ve written a patch to migration code so you can have multiple migrations with the same number. This means that these migrations can effectively be run in parallel, so long as all the migrations with that number have the IndependentMigration class.
His patch is interesting, and solves a real problem. But, his two caveats render the solution slightly too complex.
What if instead of version numbers we had migrations with timestamps ? We would need a few changes for that to be useful:
- All timestamps must be in the UTC timezone;
- The schema_info table must change (or be replaced) to have many records instead of only one.
Then, when we run the migrations, we order the migration files by name, and check if the record exists in the schema_info table. If it doesn’t, we migrate and record the time at which the migration ran.
Let’s assume we are on
trunk/. The following migrations already exists.
db/ migrate/ 20061208111503_create_posts.rb 20061208111504_create_tags.rb 20061208111505_create_taggings.rb
The migrations table I was talking about above would look something like this:
1 create_table :schema_migrations, :force => true do |t| 2 t.column :migration, :string, :limit => 20, :null => false 3 t.column :migrated_at, :datetime 4 end 5 6 add_index :schema_migrations, :migration
We have another developer who was working on another branch, and he just merged back to
trunk/. Let’s update:
1 $ svn update 2 A db/migrate/20061208161723_create_links.rb 3 A db/migrate/20061208111303_create_users.rb
Now that we have his code, let’s migrate and run the tests
1 $ rake db:migrate test:recent 2 == CreateUsers: migrating 3 ... 4 == CreateLinks: migrating 5 ... 6 7 ... 8 9 87 tests, 125 assertions, 0 failures, 0 errors
CreateUsers was run because it’s timestamp comes before CreatePosts. CreatePosts, CreateTags and CreateTaggings weren’t run because they had already been run. Finally, CreateLinks was run because it hadn’t been run yet.
The only thing missing now is the interim world. What do we do with existing migrations ? I believe we should simply migrate all low-level migrations before we do the new ones. That should ensure all migrations are up to date, no ?
I know code speaks louder than words. Just give me a couple of hours, will you ?