DataMapper does have migrations
Written on 9:27:00 AM by S. Potter
I wanted to bust a myth out there that DataMapper does not have regular migrations, just the auto migrations. At least in post 0.9 versions DataMapper has both.
In other blogs about the topic I found quotes like: "DataMapper migrations pull your database structure directly from the Ruby code for your models, so there’s no need to write separate migration files...". This, in my opinion, gives the wrong impression to those that are worried about non-trivial schema migrations. The author of that quote appears to have never moved one column into multiple or vice versa (a non-trivial schema change), among other schema changes where a DataMapper auto migration would not work in a production environment.
In merb you can just create a new DM migration with the following:$ merb-gen migration name_of_your_migration
(Assuming you have set the use_orm setting to :datamapper in config/init.rb.)
A simple DataMapper migration might look something like:
migration 1, :create_orders do
up do
create_table(:orders) do
column(:id, Integer, :serial => true)
column(:amount, Integer)
column(:completed, Boolean)
column(:description, String, :size => 255)
column(:created_at, DateTime)
column(:updated_at, DateTime)
end
end
down do
drop_table(:orders)
end
end
If you have problems with
Boolean not being recognized, throw in the line:include DataMapper::Types to the top of the migration (yes, this needs some finessing obviously).
Hope that helps a few people that may have been mislead by some blog posts inadvertently. Migrations are needed for many cases I come across where auto migrations just will not cut it without losing data in production (not a good thing if data matters in your application:)).
BTW A minor annoyance of mine in Merb is that for DM migrations you need to use this ugly Rake task:
dm:db:migrate to migrate to latest version. To rollback migrations you need to use this ugly thing: dm:db:migrate:down[version]. Where those using AR in Merb just keep using db:migrate and db:rollback. This is an area that needs cleaning up to promote ORM agnosticism the way Merb is supposed to do.
Unfortunately I had to spend some time to find the cause of migration error and want to share my solution/bug fix (maybe :)).
On the following migration
up do
create_table :sph_counter do
column :counter_id, Integer, :serial => true
column :max_doc_id, Integer, :null => false
end
end
I got the following SQL
CREATE TABLE `sph_counter`
ENGINE = InnoDB
CHARACTER SET utf8
COLLATE utf8_general_ci (`counter_id` serial PRIMARY KEY, `max_doc_id` INT(11))
Here are two little changes for fixing this (dm-migrations-0.9.11):
lib/sql/table_creator.rb:
def to_sql
"#{@adapter.create_table_statement(quoted_table_name, @columns)}"
end
lib/sql/mysql.rb:
def create_table_statement(quoted_table_name, columns)
"CREATE TABLE #{quoted_table_name} (#{columns.map{ |c| c.to_sql }.join(', ')}) ENGINE = InnoDB CHARACTER SET #{character_set} COLLATE #{collation}"
end