Rolling back a failed Rails migration

后端 未结 9 737
一向
一向 2020-12-07 17:03

How do you roll back a failed rails migration? I would expect that rake db:rollback would undo the failed migration, but no, it rolls back the previous migratio

相关标签:
9条回答
  • 2020-12-07 17:45

    Unfortunately, you must manually clean up failed migrations for MySQL. MySQL does not support transactional database definition changes.

    Rails 2.2 includes transactional migrations for PostgreSQL. Rails 2.3 includes transactional migrations for SQLite.

    This doesn't really help you for your problem right now, but if you have a choice of database on future projects, I recommend using one with support for transactional DDL because it makes migrations much more pleasant.

    Update - this is still true in 2017, on Rails 4.2.7 and MySQL 5.7, reported by Alejandro Babio in another answer here.

    0 讨论(0)
  • 2020-12-07 17:49

    Alejandro Babio's answer above provides the best current answer.

    One additional detail I want to add:

    When the myfailedmigration migration fails, it is not considered as applied, and this can be verified by running rake db:migrate:status, which would show output similar to the following:

    $  rake db:migrate:status
    database: sample_app_dev
    
     Status   Migration ID    Migration Name
    --------------------------------------------------
       up      20130206203115  Create users
       ...
       ...
       down    20150501173156  Test migration
    

    The residual effect of add_column :assets, :test, :integer being executed on the failed migration will have to be reversed at the database level with a alter table assets drop column test; query.

    0 讨论(0)
  • 2020-12-07 17:59

    The easy way to do this is to wrap all of your actions in a transaction:

    class WhateverMigration < ActiveRecord::Migration
    
     def self.up
        ActiveRecord::Base.transaction do
    ...
        end
      end
    
      def self.down
        ActiveRecord::Base.transaction do
    ...
        end
      end
    
    end
    

    As Luke Francl noted, "MySql['s MyISAM tables don't] support transactions" -- which is why you might consider avoiding MySQL in general or at least MyISAM in particular.

    If you're using MySQL's InnoDB, then the above will work just fine. Any errors in either up or down will back out.

    BE AWARE some types of actions cannot be reverted via transactions. Generally, table changes (dropping a table, removing or adding columns, etc.) cannot be rolled back.

    0 讨论(0)
  • 2020-12-07 18:00

    I had a typo (in "add_column"):

    def self.up

    add_column :medias, :title, :text
    add_colunm :medias, :enctype, :text
    

    end

    def self.down

    remove_column :medias, :title
    remove_column :medias, :enctype   
    

    end

    and then your problem (cannot undo partly failed migration). after some failed googling i ran this:

    def self.up

    remove_column :medias, :title
    add_column :medias, :title, :text
    add_column :medias, :enctype, :text
    

    end

    def self.down

    remove_column :medias, :title
    remove_column :medias, :enctype
    

    end

    as you can see i just added the correction line by hand, and then removed it again, before i checked it in.

    0 讨论(0)
  • 2020-12-07 18:01

    I agree that you should use PostgreSQL when possible. However, when you are stuck with MySQL, you can avoid most of these problems by trying your migration on your test database first:

    rake db:migrate RAILS_ENV=test
    

    You can revert to the previous state and try again with

    rake db:schema:load RAILS_ENV=test
    
    0 讨论(0)
  • 2020-12-07 18:02

    OK, folks, here's how you actually do it. I don't know what the above answers are talking about.

    1. Figure out which part of the up migration worked. Comment those out.
    2. Also comment out/remove the part of the migration that broke.
    3. Run the migration again. Now it will complete the non-broken parts of the migration, skipping the parts that have already been done.
    4. Uncomment the bits of the migration you commented out in step 1.

    You can migrate down and back up again if you want to verify that you've got it right now.

    0 讨论(0)
提交回复
热议问题