【问题标题】:Usefulness of db migrations rollback数据库迁移回滚的用处
【发布时间】:2011-04-17 15:33:49
【问题描述】:

很多人都在谈论数据库迁移,尤其是它的回滚可能性。

我怀疑它是否有用,因为 db 和 model 的模式与应用程序逻辑 (MVC) 紧​​密相连。

假设我已经完成了一些迁移的回滚。什么?该应用程序将无法运行,因为它的逻辑完全依赖于 db。

数据库迁移回滚能力的用例是什么?


更新 1

主要问题

当我需要更改代码时,为什么将回滚显示为一项功能?

创建迁移,例如“add_another_field_to_table”。相反,每个迁移文件都完整描述了 DB 中的每个表。当我需要更改数据库中的某些内容时,我只需更改迁移文件,但不要回滚

真的,如果我回滚迁移,它不会像版本控制那样让我及时回到过去。我有很多工作,当计划更改并且回滚什么都没给我时。

【问题讨论】:

  • "我不创建迁移,例如"add_another_field_to_table"。相反,每个迁移文件都完整描述了数据库中的每个表。当我需要更改数据库中的某些内容时,我只需更改迁移文件” 你能进一步解释一下吗,因为这对我来说听起来很奇怪。当您需要添加列时,您不会进行新的迁移,而是编辑旧的迁移?听起来您没有正确使用迁移...
  • 是的,在我看来也是如此。我没有注意到部分迁移的任何好处。他们只是模糊了目前迁移所发生的情况。我知道,那个 schema.rb 文件就是为了这个。但是,部分迁移只是减慢了我的工作,因为当我需要查看数据库中的某个表时,我需要跳过几个“add_column_to_table”迁移文件。但是,它们的真正好处是什么?我还不知道答案...

标签: ruby-on-rails database-migration


【解决方案1】:

回滚的重点是同时回滚代码和数据库。场景是你在生产服务器上升级你的代码和数据库,然后你发现了一个错误,你真的需要回去。所以回滚你的代码并使用你的向下迁移来回滚你的数据库。

【讨论】:

    【解决方案2】:

    向上迁移有什么意义?

    1. 您创建表结构。
    2. 您对其进行编码,它运行良好。
    3. 您将网站投入生产,每个人都很高兴。
    4. 哦,等等,他们想要一项新功能,即向现有表中添加一列。

    你如何处理这个问题?您必须在开发表中添加一列,测试代码,更新实时站点,同时不要忘记更新实时数据库(因为如果这样做会出现大错误)并且还记得保留现有的实时数据。如果没有像 rails 这样好的托管解决方案,这方面的数据库管理可能会很痛苦。

    所以...

    1. 编写添加一列的单行迁移代码
    2. 在开发副本上运行迁移,scehma.rb 将更新
    3. 编码新功能,如果您需要检查 DB 架构,请使用 schema.rb 而不是迁移文件。

    现在您已准备好在生产环境中发布 ....

    1. 在生产环境中更新代码
    2. 在生产环境中运行迁移。 Rails 会自动计算出需要应用的内容并为您完成!

    当然,您添加一列后,您自己做也不会那么混乱。

    但是如果有 3 个程序员都在添加迁移呢?如果您有许多实时站点,并且都具有不同的版本,该怎么办?那个 live site 2 或 17 迁移落后了吗?在保留实时数据的同时,我需要做什么才能让数据库获得最新的代码?你能看出这很快就会让人感到困惑吗?

    Rails 迁移(几乎每个迁移系统都按照相同的原则工作)旨在使更新数据库结构变得非常容易。非常值得正确使用。

    【讨论】:

      【解决方案3】:

      我发现回滚只有在本地完成时才有用,即在您处理新代码时。一旦将迁移提交到您的版本控制系统中,如果您意识到有一个错误,那么回滚迁移就不会真正起作用,因为其他开发人员会拉下迁移并运行它,所以您需要告诉他们也回滚——这太难管理了,也让你看起来无能:)

      在这种情况下,最好再进行一次迁移来解决问题,然后每个人(包括您的生产服务器)都坚持使用 pull & migrate 系统。

      【讨论】:

      • 我同意这似乎是最常见的用例。像 OP 一样,我看不到主要数据库回滚过程的真正好处。大多数健全的模式更新在设计上都是非破坏性的,正是因为在应用更新时消费的生产软件不能中断。因此,即使您必须回滚生产代码,您通常也可以保留更新后的架构,然后在必要时简单地应用一些额外的迁移,而不是回滚并重新应用原始迁移的修改版本。
      【解决方案4】:

      不太了解您的问题,但我尝试解释一下回滚。 如果要撤消相应迁移的更改,请执行回滚。这意味着数据库将被修改,并且您的 schema.rb 也将自动重新生成。当您这样做时,您可能也想删除引用代码。例如,如果您从模型中删除了一个字段,您可能不想在代码中引用该属性。如果您尝试访问,则会给​​您未定义的属性异常。而已。 例如,如果您之前创建了一些模型 10 迁移,并且您想要更改某些字段,则回滚可能会变得有点麻烦。最好创建一个新的迁移并在那里修改,而不是回滚到相应的迁移。

      更新 1

      阅读您的更新,我认为您没有使用迁移的主要优势,即灵活性。 但是您的解决方案提供了对数据库情况的更多概述。如果您喜欢这样做,我建议按顺序执行以下步骤。

      1. 回滚到相应的迁移。(rake db:migrate VERSION=XXX,我更喜欢 rake db:rollback STEP = 2 例如,回滚 2 个迁移,STEP 可选)
      2. 进行更改
      3. 迁移您的数据库以更新所有表,并获取当前迁移版本。(rake db:migrate)

      此功能不会影响您的模型或其他东西,只是更改迁移文件,重新生成您的 schema.rb 并更改数据库结构,没有别的。不能像版本控制系统那样做代码回滚,而且做这样的事情也没有意义。您必须注意不要使用已删除的字段。 Rails 具有数据库字段和模型属性之间的自动映射,例如,如果您的 comment 表中有一个 user_id,您可以将其作为模型中的属性调用,comment_instance.user_id

      【讨论】:

      • 我想明白了,迁移的全部内容。他们在生产服务器的数据库中保留数据。我可以在不触及其他表中的数据的情况下进行小的修改。我说的对吗?
      • 好吧,如果您像使用迁移一样使用迁移,那么您也必须在生产模式下执行这 3 个步骤,(步骤 1,3 可以),但这有点 hacky,那就是为什么在更改数据库时使用新的迁移,以便在更新生产模式下的更改时也避免这种黑客攻击。无论如何,由于组织,您不需要像以前那样使用迁移,您的表的字段可以在不同的迁移中,您不会因为 schema.rb 而迷路。如果您需要表格的结构,您可以从那里获得。
      【解决方案5】:

      假设您使用 capistrano 部署站点并为每个部署创建时间戳快照。使用文件夹上的时间戳和您的迁移,您可以确定哪些版本的代码和架构齐头并进并执行回滚。

      git 存储库会为您提供类似的选项。

      当然,真正的问题是,一旦网站的用户开始添加数据,这些数据也可能会被清除,除非您在回滚之前对其进行备份并在以后煞费苦心地恢复它。

      【讨论】:

        【解决方案6】:

        在处理迁移代码和最终提交之前,我使用 rake db:migrate:redo 在本地使用迁移回滚。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-06-30
          • 1970-01-01
          • 2013-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-07
          相关资源
          最近更新 更多