【问题标题】:How to rollback a specific migration?如何回滚特定的迁移?
【发布时间】:2011-04-08 13:00:01
【问题描述】:

我有以下migration 文件db\migrate\20100905201547_create_blocks.rb

如何专门回滚该迁移文件?

【问题讨论】:

  • 这是否解决了问题?你只需要Class.downstackoverflow.com/questions/753919/run-a-single-migration-file
  • 关于迁移的所有信息Here
  • 您是否只想回滚那个单一的特定迁移(即使之后有更新的迁移)?还是要将数据库回滚到迁移之前的状态,以及应用任何后续迁移之前的状态?

标签: ruby-on-rails schema database-schema rollback


【解决方案1】:
rake db:rollback STEP=1

如果要回滚的迁移是最后一次应用的迁移,则可以这样做。您可以将 1 替换为您想要返回的任意数量的迁移。

例如:

rake db:rollback STEP=5

还将回滚后来发生的所有迁移(4、3、2 和 1)。

要将所有迁移回滚到(包括)目标迁移,请使用:(此更正的命令是在所有 cmets 指出原始帖子中的错误之后添加的)

rake db:migrate VERSION=20100905201547

为了只回滚一个特定的迁移(无序),请使用:

rake db:migrate:down VERSION=20100905201547

请注意,这不会回滚任何中间迁移 - 只会回滚列出的迁移。如果这不是你想要的,你可以安全地运行rake db:migrate,它只会重新运行那个,跳过之前没有回滚的任何其他。

如果你想迁移一个无序的迁移,还有它的逆db:migrate:up

rake db:migrate:up VERSION=20100905201547

【讨论】:

  • “为了回滚到特定版本” - 后面的命令不是只回滚特定迁移,而不是一直回滚到那个版本吗?
  • "为了回滚到特定版本使用..." 这个答案不正确!这将像其他答案所解释的那样单独回滚迁移。
  • 警告:我犯了这个错误:只使用 rake db:migrate:down VERSION=20100905201547 在隔离中回滚!!!一个迁移文件。上面的评论中提到了这一点,但我错过了。
  • 另一个警告——永远不要这样做STEP=-1。我这样做了一次,它发疯了,回滚了一切。不是很好!这是 Rails 4.2 - 我想它现在可能已经修复了。
  • 别忘了您可以使用rake db:migrate:status 查看所有具体的迁移及其状态!
【解决方案2】:
rake db:migrate:down VERSION=20100905201547

将回滚特定文件。


要查找所有迁移的版本,可以使用以下命令:

rake db:migrate:status

或者,迁移文件名的前缀就是你需要回滚的版本。


请参阅 the Ruby on Rails guide entry 了解迁移。

【讨论】:

  • 在我看来绝对是首选答案。
  • 值得一提的是,如果您回滚特定迁移并且不希望它在即将到来的 rake 任务中重新迁移,那么也请删除迁移文件。
  • 注意:似乎如果向上迁移从未成功但只是部分执行,那么向下迁移什么也不做。
  • @nerith,这可能只适用于不支持事务 DDL 的数据库。 MySQL 不支持 Transactional DDL:dev.mysql.com/doc/refman/5.0/en/cannot-roll-back.html PostreSQL 支持:wiki.postgresql.org/wiki/… 因此,如果您在 MySQL 数据库上的迁移被破坏,那么您必须手动删除成功的迁移部分。
  • 关于@BradGreens 评论的另一个观察结果。如果您确实要删除迁移文件,并且它已经部署,您需要在提交带有已删除文件的代码之前回滚生产/登台。否则你将无法回滚/迁移:down。
【解决方案3】:

要回滚您可以执行的最后一次迁移:

rake db:rollback

如果您想回滚某个版本的特定迁移,您应该这样做:

rake db:migrate:down VERSION=YOUR_MIGRATION_VERSION

例如如果版本是20141201122027,你会这样做:

rake db:migrate:down VERSION=20141201122027

回滚特定的迁移。

【讨论】:

    【解决方案4】:

    您可以使用 rake db:rollback 和不同的选项来回滚您的迁移。语法会根据您的要求而有所不同。

    如果您只想回滚上次迁移,那么您可以使用任一

    rake db:rollback
    

    rake db:rollback STEP=1
    

    如果您想一次回滚迁移数量,那么您只需传递一个参数:

    rake db:rollback STEP=n
    

    其中n 是要回滚的迁移数,从最近的迁移开始计数。

    如果你想回滚到特定的迁移,那么你应该在下面传递迁移的版本:

    rake db:migrate:down VERSION=xxxxx
    

    其中 xxxxx 是迁移的版本号。

    【讨论】:

    • 添加 :down 不起作用,正确答案是没有 down
    【解决方案5】:

    rake db:migrate:down VERSION=your_migrations's_version_number_here

    版本是迁移文件名的数字前缀

    如何找到版本

    您的迁移文件存储在您的rails_root/db/migrate 目录中。找到您要回滚到的相应文件并复制前缀号。

    例如

    文件名:20140208031131_create_roles.rb 那么版本是20140208031131

    【讨论】:

    • 查找迁移id最简单的方法是运行rake db:migrate:status
    【解决方案6】:

    回滚上次迁移:

    # rails < 5.0
    rake db:rollback
    
    # rails >= 5.0
    rake db:rollback
    # or
    rails db:rollback
    

    回滚上次 n 迁移次数

    # rails < 5.0
    rake db:rollback STEP=2
    
    # rails >= 5.0
    rake db:rollback STEP=2
    # or
    rails db:rollback STEP=2
    

    回滚特定迁移

    # rails < 5.0
    rake db:migrate:down VERSION=20100905201547
    
    # rails >= 5.0
    rake db:migrate:down VERSION=20100905201547
    # or
    rails db:migrate:down VERSION=20100905201547
    

    【讨论】:

      【解决方案7】:

      要回滚您可以执行的最后一次迁移:

      rake db:rollback
      

      如果您想回滚某个版本的特定迁移,您应该这样做:

      rake db:migrate:down VERSION=YOUR_MIGRATION_VERSION
      

      如果您要回滚的迁移文件名为 db/migrate/20141201122027_create_some_table.rb,则该迁移的 VERSION 为 20141201122027,这是创建该迁移的时间戳,回滚该迁移的命令为:

      rake db:migrate:down VERSION=20141201122027
      

      【讨论】:

        【解决方案8】:

        要将所有迁移回滚到特定版本(例如20181002222222),请使用:

        rake db:migrate VERSION=20181002222222
        

        (请注意,这使用db:migrate - 而不是db:migrate:down,如该问题的其他答案。)

        假设指定的迁移版本比当前版本旧,这会将所有迁移回滚到指定版本,但不包括指定版本。

        例如,如果 rake db:migrate:status 最初显示:

          (... some older migrations ...)
          up      20181001002039  Some migration description
          up      20181002222222  Some migration description
          up      20181003171932  Some migration description
          up      20181004211151  Some migration description
          up      20181005151403  Some migration description
        

        跑步:

        rake db:migrate VERSION=20181002222222
        

        将导致:

          (... some older migrations ...)
          up      20181001002039  Some migration description
          up      20181002222222  Some migration description
          down    20181003171932  Some migration description
          down    20181004211151  Some migration description
          down    20181005151403  Some migration description
        

        参考:https://makandracards.com/makandra/845-migrate-or-revert-only-some-migrations

        【讨论】:

          【解决方案9】:

          如果是可逆迁移并且是最后一个已执行的迁移,则运行rake db:rollback。而且您始终可以使用版本。 例如

          迁移文件是20140716084539_create_customer_stats.rb,所以回滚命令是, rake db:migrate:down VERSION=20140716084539

          【讨论】:

            【解决方案10】:

            来自Rails Guide

            恢复以前的迁移

            您可以通过 revert 方法使用 Active Record 的回滚迁移功能:

            require_relative '20100905201547_create_blocks'
            
            class FixupCreateBlock < ActiveRecord::Migration
              def change
                revert CreateBlock
            
                create_table(:apples) do |t|
                  t.string :variety
                end
              end
            end
            

            revert 方法还接受要反转的指令块。这对于还原先前迁移的选定部分可能很有用。例如,假设 CreateBlock 已提交,后来决定最好使用 Active Record 验证来代替 CHECK 约束来验证邮政编码。

                class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration
                  def change
                    revert do
                      # copy-pasted code from CreateBlock
                      reversible do |dir|
                        dir.up do
                          # add a CHECK constraint
                          execute <<-SQL
                            ALTER TABLE distributors
                              ADD CONSTRAINT zipchk
                                CHECK (char_length(zipcode) = 5);
                          SQL
                        end
                        dir.down do
                          execute <<-SQL
                            ALTER TABLE distributors
                              DROP CONSTRAINT zipchk
                          SQL
                        end
                      end
            
                      # The rest of the migration was ok
                    end
                  end
                end
            

            同样的迁移也可以在不使用 revert 的情况下编写,但这将涉及更多步骤:颠倒 create_table 和 reversible 的顺序,将 create_table 替换为 drop_table,最后将 up 替换为 down,反之亦然。这一切都由 revert 处理。

            【讨论】:

              【解决方案11】:

              迁移使用命令改变数据库的状态

              $ bundle exec rake db:migrate
              

              我们可以使用

              撤消单个迁移步骤
                $ bundle exec rake db:rollback
              

              要一直回到开头,我们可以使用

                $ bundle exec rake db:migrate VERSION=0
              

              正如您可能猜到的那样,将任何其他数字替换为 0 会迁移到该版本号,其中版本号来自按顺序列出的迁移

              【讨论】:

                【解决方案12】:

                如果你想回滚和迁移你可以运行:

                rake db:migrate:redo
                

                同理:

                rake db:rollback
                rake db:migrate
                

                【讨论】:

                  【解决方案13】:

                  在 Rails 5 中这很容易 耙分贝:迁移:状态 要么 rails db:migrate:status

                  它被修改为以相同的方式处理 然后只需选择要回滚的版本 然后运行 rake db:migrate VERSION=2013424230423

                  确保VERSION全是大写字母

                  如果您在迁移的任何步骤中遇到问题或卡在中间,只需转到迁移文件并注释掉已经迁移的行。

                  希望对你有帮助

                  【讨论】:

                  • 我突出显示命令 rake db:migrate:status 的提示。 . .查看迁移文件的当前执行状态非常适合概览。
                  【解决方案14】:

                  另外

                  当您很久以前部署的迁移不允许您迁移新的。

                  发生的情况是,我在一个包含一千多个迁移文件的大型 Rails 应用程序中工作。而且,我们需要一个月的时间才能发布一个中型功能。我正在开发一个功能,一个月前我已经部署了一个迁移,然后在审查过程中迁移的结构和文件名发生了变化,现在我尝试部署我的新代码,构建失败说

                  ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR:  column "my_new_field" of relation "accounts" already exists
                  

                  上述解决方案都不适合我,因为缺少旧的迁移文件,并且我打算在新迁移文件中创建的字段已经存在于数据库中。唯一对我有用的解决方案是:

                  1. scped 文件到服务器
                  2. 我打开了rails console
                  3. 我在 IRB 会话中需要该文件
                  4. 然后AddNewMyNewFieldToAccounts.new.down

                  然后我可以再次运行部署构建。

                  希望对你也有帮助。

                  【讨论】:

                    【解决方案15】:

                    对于多数据库配置(RoR >= v6),您必须在命令中附加数据库名称,例如:

                    • rails db:rollback:primary,其中 primary 是您的 config/databases.yml 文件中的数据库名称,用于回滚上次迁移。您可以像往常一样在此处使用 STEPS 属性。
                    • rails db:rollback:primary VERSION=your_migration_timestamp,仅回滚提供的迁移版本。这里 primary 也是数据库的名称。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2014-06-21
                      • 2017-02-24
                      • 2017-03-18
                      • 2017-10-21
                      • 2016-08-19
                      • 2017-10-25
                      • 2013-07-15
                      • 2018-01-05
                      相关资源
                      最近更新 更多