Rails Migrations aren't atomic
This note is applicable to Rails 1.1.6.5618 (which is really Rails 1.2 Release Candidate)
If you use the migrations feature to keep track of and control schema changes, you should be aware that a migration involves two steps and that these aren't atomic. This can come to bite you as we shall see.
First, what are the two steps?
Step 1: Make the changes to your application tables
Step 2: Update the schema_info table
Suppose that your schema version is currently 3 i.e. the value of the version field of the schema_info table is 3. Next say, you have developed the following schema change (004_add_create_date_and_usage.rb)
When you run this by issuing the command rake db:migrate it will obviously fail when it tries to add the field usage_count since number is not a valid type. The rake task quits at this stage. If you check the database you will see that the table mytable now has a created_at field, no usage_count field and that the schema_info table says the version is still 3. Oops!
No problem, you think. I'll just run rake db:migrate VERSION=3 and all will be back to the way it was. You can then fix the mistake and run the migration again. WRONG ANSWER!
The trouble is that since SCHEMA_INFO.VERSION=3 running rake db:migrate VERSION=3 does nothing!
The way around it to manually edit the schema_info table and set the value of version to 4 and then run rake db:migrate VERSION=3.
If you use the migrations feature to keep track of and control schema changes, you should be aware that a migration involves two steps and that these aren't atomic. This can come to bite you as we shall see.
First, what are the two steps?
Step 1: Make the changes to your application tables
Step 2: Update the schema_info table
Suppose that your schema version is currently 3 i.e. the value of the version field of the schema_info table is 3. Next say, you have developed the following schema change (004_add_create_date_and_usage.rb)
class AddCreateDateAndUsage < ActiveRecord::Migration
def self.up
add_column :mytable, :created_at, :datetime
add_column :mytable, :usage_count, number
end
def self.down
remove_column :mytable, :created_at
remove_column :mytable, :usage_count
end
end
When you run this by issuing the command rake db:migrate it will obviously fail when it tries to add the field usage_count since number is not a valid type. The rake task quits at this stage. If you check the database you will see that the table mytable now has a created_at field, no usage_count field and that the schema_info table says the version is still 3. Oops!
No problem, you think. I'll just run rake db:migrate VERSION=3 and all will be back to the way it was. You can then fix the mistake and run the migration again. WRONG ANSWER!
The trouble is that since SCHEMA_INFO.VERSION=3 running rake db:migrate VERSION=3 does nothing!
The way around it to manually edit the schema_info table and set the value of version to 4 and then run rake db:migrate VERSION=3.