为什么我要恢复迁移?

时间:2010-02-21 15:27:33

标签: ruby-on-rails migration

在Rails中,默认情况下,迁移具有down方法以恢复迁移。但是,在什么情况下我还想恢复迁移?

一些想法:

无论是在开发还是生产中,在我运行迁移之前,我总是会有一个我的数据库快照。特别是对于执行数据转换的迁移,我发现在大多数情况下恢复快照甚至比恢复迁移更快。 (所以我绝不会急于做!)

如果迁移失败,则会:

  • 在非事务性数据库上失败并出现异常,从而导致数据库中断或
  • 因异常而失败并回滚事务,因此不需要还原。

如果所做的更改是在生产中(或在开发的后期),后来证明是一个错误,我会在新的迁移中修复我的错误。我会还原旧的。在开发中,我只是删除迁移。

我还发现down方法引入了额外的代码,我重复自己,因此可能会引入新的bug。这违反了DRY原则。

所以我对专业人士很好奇,因为我想不出任何一个。

4 个答案:

答案 0 :(得分:4)

在开发过程中,通过自动使用down方法,可以轻松快速地逐步“改进”迁移。例如

  1. 创建迁移并迁移到它
  2. 意识到你需要做出改变
  3. 使用db:migrate with version
  4. 迁移到新迁移之前的ver
  5. 改善/修复您的迁移
  6. 重新运行迁移任务
  7. 拍摄快照的方法很好。但是rails使用“向下”迁移技术自动神奇地包含相同的效果。适用于所有数据库,味道很棒

    补充:

    对于生产,我同意不应该需要向下迁移。但有时会发生错误,你需要回滚。向下迁移路径为您提供了第一个快速机会,可以在出现错误的升级过程中解决紧急情况。

    - 在紧急情况下尝试向下迁移比使用检查点恢复数据库要快得多。

答案 1 :(得分:2)

用于数据库回滚的“向下”迁移已经到位,因此每个操作都有相同且相反的操作。它需要开发人员的责任来维护数据库快照,并允许他们使用代码来实现相同的目的。正如Larry K所说, 他们对这样的情况有好处:

  • 添加一个名为'resubmitted'的数据库列,它是一个布尔值。
  • 产品所有者说他们可以多次重新提交,因此更改该列需要为int

现在,如果你进行了10或15次迁移,那么通过执行回滚就可以更轻松地编写新的迁移,而不是丢失新表/列中的所有dev数据。但是,如果您刚刚编写了该迁移,那么它就会更清晰,更简洁,可以回滚,更改迁移并重新运行。

回滚的另一个非常有用的功能是:

  • 开发人员1拥有自己的Dev DB。他编写了一个迁移并运行它。
  • 开发人员1提交迁移到源代码管理
  • 开发人员2拥有自己的Dev DB。她写了一个迁移并运行它。
  • 开发人员2从源代码管理中更新
  • 开发人员2尝试运行迁移,但不能,因为她的本地数据库说“已经运行了最新的迁移”,因为她的迁移(最新版本)已经运行技术 。现在她需要回滚,然后执行db:migrate以获取本地数据库中的所有迁移。

答案 2 :(得分:2)

在生产中运行向下迁移的想法让我感到恐惧。当回滚所有迁移的首选方法是rake db:migrate VERSION=0时,我会在开发过程中一直这样做。然而,然后我变得偏执,因为它致力于肌肉记忆,当我打算简单地迁移时,我会不小心在生产服务器上输入它。

由于这种偏执,我将以下所有方法添加到以下方法中。

  def self.down
    if Rails.env.production?
      raise ActiveRecord::IrreversibleMigration
    else
      drop_table :foo_bars
    end 
  end 

通过这种方式,它仍然可以在开发中使用,但是我不能在凌晨2点半睡半醒时将我的生产数据库从轨道上无意中编入。

答案 3 :(得分:0)

当迁移没有达到预期的结果时,最好回滚并重写它,而不是将失败的迁移保留在代码中。