修改现有的 Rails 迁移是一个好主意吗?

7
在开始新项目时,模型中可能会有很多变化,我发现编辑现有的迁移并运行db:cleandb:reset比创建新的迁移容易。当应用程序尚未投入生产使用时,我会这样做,这意味着我可以放心地重置/清理数据库,而且我是独自工作或者是小团队的一部分。
但是今天,我在Rails Guide中看到了以下建议,称其不是一个好主意,不鼓励编辑现有的迁移:

编辑现有的迁移不是一个好主意:这将为您和您的同事创建额外的工作,并在现有版本的迁移已经在生产机器上运行时引起重大头痛。相反,您应该编写一个新的迁移,执行您需要的更改。编辑尚未提交到源代码控制(或更一般地说,尚未传播到您的开发机器之外)的新生成的迁移是相对无害的。

我想知道:
  • 我可能会遇到哪些潜在问题?
  • 这些问题是否适用于我的情况(开发阶段、独立工作)?

为什么不自己体验一下呢? :) - Amol Pujari
我已经在做了 :) - CuriousMind
这让我想起我们曾经在迁移中使用全局常量,这些常量定义在某个constant.rb文件中,后来被某人编辑了 :) 所以要点是,在迁移中始终使用硬编码的值,没有变量,也没有常量。 - Amol Pujari
同意!然而,如果我刚创建了一个模型并想要更改它,我发现直接编辑迁移更容易。在进程的早期阶段留下审计轨迹没有任何意义。 - CuriousMind
4个回答

10
如果您正在与团队合作并且已经提交了迁移,则不能这样做。
如果只是在本地环境上进行操作,那么只需创建一个新的迁移来修复您需要的内容。您可以删除表格/列并进行必要的更改。
由于您清理了数据库并将其重置,因此每个人都将执行相同的操作,否则他们尝试迁移时会遇到问题。

是的,我在我的本地环境中。所以我想这没问题。只是想确认一下。谢谢回复。 - CuriousMind
你也可以从Rails控制台迁移数据库:ActiveRecord::Migration.some_migration_method(...) - tokland
@tokland,我尝试了ActiveRecord::Migration.up.create_table("test"),但它显示未定义的方法。语法是什么? - CuriousMind

1

我正在开发模式下开发一个Web应用程序。虽然我是独自工作,但最好使用迁移来修改数据库。这可能会留下一些修改的痕迹,但您可以看到数据库结构的演变。从长远来看,您将通过迁移更快地解决数据库问题。


1
请问您能否添加更多的内容来帮助提问者,例如哪些陷阱和/或如何学习“最佳实践”?谢谢!(审核中) - Gayot Fow

0

数据库迁移是一种工具。像任何工具箱一样,最重要的是要了解它的用途、如何使用以及为什么要以这种方式使用。

  • 现场运行:在现场运行中,您不能简单地使用rake:db reset,因为您显然需要所有那些数据
  • 协作开发:您需要与其他开发人员保持迁移的一致性。如果他们已经将数据输入到他们的数据库中(出于任何目的),并且只是混合了您的代码。您现在完全破坏了他们的努力,他们将被迫重置整个数据库
  • Rake db:rollback:一旦您修改了代码,您就必须进行重置,现在您无法运行回滚。
  • 这是一个不好的习惯:在大多数情况下,礼貌的做法是创建一个新的迁移。最好养成这种习惯和思维方式,能够快速高效地创建新的迁移。

我实际上并不是告诉你不要这样做。这些只是我认为为什么不要这样做的主要观点。在大多数情况下,如果你是一个人,或者特别是在组建项目时(可能还没有立即意识到你想要数据库看起来/工作起来的方式),直接对其进行尝试可能是最有效的。在违反最佳实践之前,了解为什么和何以及何处很重要。


0

一旦你将迁移提交到git,只要它不是破坏数据或CI崩溃的事情,你就不应该改变它。这是整个概念的公理!

问题在于,一旦应用了迁移,它就不会再次运行,如果你必须回滚到它,你就冒着意外数据丢失的风险。你应该总是创建一个新的迁移。

有一个例外情况,与移除依赖项有关,这是一个棘手的问题。涉及第三方ORM的迁移面临的问题之一是依赖关系是二选一的事情。它们要么存在,要么不存在。因此,如果在某个时刻添加了一个依赖项,然后从模型中创建外键引用,并将其存储在迁移中,然后稍后删除该依赖项,则当您从头运行迁移时,与迁移中链接的依赖项将失败,因为外键的目标已经不存在了。这是一个非常棘手的问题,因为在这种情况下,您实际上需要编辑旧的迁移以删除外键,但您还需要进行迁移以删除现有安装的密钥。这里的一般模式是,如果您的迁移系统是可脚本化的,请添加一个检查以查看密钥是否存在,然后仅在存在时删除密钥,否则跳过删除。顺便提一下,try {} except {}类型的结构可能不是正确的选择,因为一些ORM会回滚到写入时排队的事务,以避免损坏。

因此,通常情况下,请不要编辑现有的迁移,但如果在那些外部因素决定要求的有限情况下,请非常小心地进行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接