{ height: 1%; } - Ruby on Rails and User Interface Design

CSS, UI Design, Ruby on Rails and cheese ... lots of cheese

On the need for more robust Rails Migrations

Posted by Richard White Sat, 18 Feb 2006 02:06:00 GMT

One of the most frustrating parts of Rails Migrations is the fact that each migration is NOT transactional. Its possible that some query halfway through the migration could fail and leave you database schema in a “bad state”. After reading this blurb on RailsBestPractices on the RoR wiki I thought that it might be possible to wrap my migrations in a simple transaction, with the only caveat that it won’t work for MySQL:
... Put a transaction around your migrations. That way, you know that you won’t be dumped out half-way through a migration, and have to disentangle whatever half-finished mess you end up with to try to run it again. The slight crimp to this is that MySQL doesn’t allow data definition commands (like CREATE TABLE, for instance) inside a transaction, and they cause an implicit commit. It’s still a good idea for data-only migrations, though.
Unfortunately the following does not work
class TestTransaction
self.up
<strong>    transaction do</strong>
    create_table :widgets, :force => true do |t|
      t.column :name, :string, :null => false
      t.column :version, :string, :null => false
    end
    remove_column :widgets, :type
  end
end

...
Because when I run rake migrate I get the following
rake aborted!
RuntimeError: ERROR   
C25P02  Mcurrent transaction is aborted, commands ignored until
end of transaction block      
Fpostgres.c     L926    Rexec_simple_query: CREATE TABLE cars
("id" serial primary key, "make" character varying(255) NO
T NULL, "model" character varying(255) NOT NULL)

If anyone has any ideas drop me a line rrwhite AT gmail.com

Update: Thanks to Eric Pugh for pointing out that removing :force => true makes this work!

Comments

  1. Dominic Mitchell said 9 days later:

    I came across this a few days ago. Basically, CREATE TABLE and friends aren’t transactional in MySQL (14.2.10.9. Implicit Transaction Commit and Rollback). You’re stuffed, basically. Probably the best you can do is stick any data modifications inside a transaction, after creating a table.

    Or use PostgreSQL. ;-)

  2. Richard White said 10 days later:

    Dominic: Actually I am using PostgreSQL (notice the Fposgres.c in the error) and still couldn’t get it to work. I guess I should have been more clear about that.

  3. Simon Harris said 730 days later:

    I’ve had a plugin for quite some time now that does exactly this. It even handles the force => true problem for you but only issuing the delete command if the table exists. You can find the plugin here: http://www.redhillonrails.org/#transactional_migrations

  4. roger father son matching said 898 days later:

    I REALLY wish that this could become a plugin for rails. Some how…someone…anyone! :) -R

Trackbacks

Use the following link to trackback from your own site:
http://www.height1percent.com/articles/trackback/7

  1. From Viagra.
    Natural viagra.
    Viagra. Generic viagra. Buy viagra. Viagra hgh.

(leave url/email »)

   Comment Markup Help Preview comment