Rails: Is it bad to have an irreversible migration?

前端 未结 7 619
隐瞒了意图╮
隐瞒了意图╮ 2020-12-24 10:57

When is it acceptable to raise an ActiveRecord::IrreversibleMigration exception in the self.down method of a migration? When should you take the effort to actually implemen

相关标签:
7条回答
  • 2020-12-24 11:40

    Reversible Data Migration makes it easy to create reversable data migrations using yaml files.

    class RemoveStateFromProduct < ActiveRecord::Migration
      def self.up
        backup_data = []
        Product.all.each do |product|
          backup_data << {:id => product.id, :state => product.state}
        end
        backup backup_data
        remove_column :products, :state
      end
      def self.down
        add_column :products, :state, :string
        restore Product
      end
    end
    
    0 讨论(0)
  • 2020-12-24 11:46

    Feeling like you need an irreversible migration is probably a sign you've got bigger problems looming. Maybe some specifics would help?

    As for your second question: I always take the 'effort' to write the reverse of migrations. Of course, I don't actually write the .down, TextMate inserts it automatically when creating the .up.

    0 讨论(0)
  • 2020-12-24 11:47

    IIRC, you'll have the IrreversibleMigration when changing a datatype in the migration.

    0 讨论(0)
  • 2020-12-24 11:47

    I think another situation when it's ok is when you have a consolidated migration. In that case a "down" doesn't really make sense, as it would drop all the tables (except tables added after the consolidation). That's probably not what you'd want.

    0 讨论(0)
  • 2020-12-24 11:51

    In a production scenario, you should always make the effort to write and test a reversible migration in the eventuality that you go through it in production, then discover a bug which forces you to roll back (code and schema) to some previous revision (pending some non-trivial fix -- and an otherwise unusable production system.)

    Having a reversible migration is fine for development and staging, but assuming well tested code it should be extremely rare that you would ever want to migrate down in production. I build into my migrations an automatic IrreversibleMigration in production mode. If I really needed to reverse a change, I could use another "up" migration or remove the exception. That seems sketchy though. Any bug that would cause a scenario this dire is a sign that the QA process is seriously screwed up.

    0 讨论(0)
  • 2020-12-24 11:54

    If you are destroying data, you can make a backup of it first. e.g.

    def self.up
      # create a backup table before destroying data 
      execute %Q[create table backup_users select * from users]  
      remove_column :users, :timezone
    end  
    
    def self.down
      add_column :users, :timezone, :string  
      execute %Q[update users U left join backup_users B on (B.id=U.id) set U.timezone = B.timezone]
      execute %Q[drop table backup_users]  
    end
    
    0 讨论(0)
提交回复
热议问题