何时(如果)整合ActiveRecord迁移?

时间:2009-09-28 11:11:09

标签: ruby-on-rails ruby activerecord migration

当我浏览应用程序*(s)的迭代时,我会累积迁移。截至目前,共有48个这样的文件,大约持续24个月的活动。

我正在考虑使用我当前的schema.rb并将其作为基线。

我也在考虑删除(当然是源代码控制)现有的迁移,并从我当前的架构中创建一个漂亮的新单一迁移?迁移往往喜欢符号,但rake db:schema:dump使用字符串:我应该关心吗?

这看起来合情合理吗? 如果是这样,这种练习在什么样的时间间隔内有意义呢? 如果没有,为什么不呢?

我是否错过了一些(耙?)任务可以为我做这件事?

*就我而言,所有应用都是基于Rails的,但使用ActiveRecord迁移的任何内容似乎都符合这个问题。

6 个答案:

答案 0 :(得分:35)

是的,这是有道理的。有一种巩固迁移的做法。为此,只需将当前架构复制到迁移中,然后删除所有早期迁移。然后,您需要管理的文件更少,测试可以更快地运行。 您需要小心执行此操作,尤其是在生产中自动运行迁移时。我通常会替换一个我知道每个人都使用新架构运行的迁移。

其他人的方法略有不同。

在我们进行了100多次迁移之前,我通常都没有这样做,但是经过几个月的开发,我们可以做到这一点。然而,随着项目的成熟,迁移的次数越来越少,因此您可能不必再次进行迁移。

这违反了最佳做法:一旦您检入迁移到源代码管理,请不要更改它。如果一个中存在错误,我会做一个罕见的例外,但这种情况非常罕见(100个中可能有1个)。原因是,一旦他们出现在野外,有些人可能会经营它们。它们被记录为在db中完成。如果您更改它们并签入新版本,其他人将无法获得更改的好处。您可以要求人们回滚某些更改并重新运行它们,但这会破坏自动化的目的。经常做,它变得一团糟。最好不要管它。

答案 1 :(得分:7)

我认为有两种迁移方式:

  • 您在设计/开发过程中所做的那些,因为您改变了对数据库应该如何的想法;

  • 您在发布之间进行的操作,反映了一些行为更改。

我尽快摆脱了第一种迁移,因为它们并不真正代表工作版本,而是保留第二种迁移,因此理论上可以更新应用程序。

关于符号与字符串:许多人认为在迁移中只应使用字符串:符号是对象的“句柄”,不应用于表示名称(在本例中为列和表名)。这仅仅是一种风格上的考虑,但让我信服,而且我不再在迁移中使用符号。

我已经读到了使用字符串的另一个观点:“ ruby​​符号是内存泄漏”,这意味着,当您创建符号时,它永远不会在所有应用程序生命周期中被处理掉。这对我来说似乎毫无意义,因为所有的db列都将用作Rails(和ActiveRecord)应用程序中的符号;迁移任务也不会永远存在,所以我认为这一点实际上并不合理。

答案 2 :(得分:4)

进行大量迁移是一件好事。结合您的版本控制系统,它们允许您查看开发人员对数据库进行了哪些更改以及原因。这有助于问责制。删除它们只会让这很麻烦。

如果您真的想要快速启动并运行新数据库,可以使用rake db:schema加载模式:加载RAILS_ENV = your_environment,如果您想快速完成测试数据库设置,可以使用rake db:测试:制备

话虽如此,如果你真的想要整合你的迁移,那么我会创建一个新的迁移,检查你的集合中最后一次迁移是否已经执行(例如:你添加的列是否存在?)和如果没有,那么它会开火。否则,迁移只会将自身添加到架构表中,因此它不会再次尝试触发。

只是将你正在做的事情传达给团队的其他成员,以便他们了解正在发生的事情,以免他们盲目地解雇rake db:迁移并搞砸他们已经拥有的东西。

答案 3 :(得分:3)

schema.rb的顶部声明:

# This file is auto-generated from the current state of the database. Instead of editing this file, 
# please use the migrations feature of Active Record to incrementally modify your database, and
# then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your database schema. If you need
# to create the application database on another system, you should be using db:schema:load, not running
# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended to check this file into your version control system.

我必须赞同[giorgian]上面提到的关于不同目的的不同迁移的内容。我建议清理面向开发的迁移以及分支发布时执行的其他任务。这对我,我自己和小团队来说都很有用。当然,我的主要应用程序位于其他两个数据库之上,并且具有自己的模式,我必须小心,因此我们使用迁移(而不是模式恢复)进行新安装,并且需要在发布工程中继续使用。

答案 4 :(得分:1)

虽然我确信每个人都有自己的做法,但迁移系统的工作方式暗示了一些规则:

  • 永远不要对其他开发人员或以前部署可能已使用的迁移进行更改。而是进行额外的迁移以根据需要调整内容。
  • 永远不要在迁移中放置模型级依赖项。可以在将来的某个时间点重命名或删除模型,这将阻止迁移。尽可能保持迁移的自包含,即使这意味着它非常简单和低级别。

当然也有例外。例如,如果迁移不起作用,无论出于何种原因,可能需要修补程序才能使其更新。但即便如此,迁移所带来的变化的性质也不应改变,尽管它们的实施可能会发生变化。

任何成熟的Rails项目都可能有大约200到1000次迁移。根据我的经验,除了规划阶段外,看到一个小于30的项目是不寻常的。毕竟,每个模型通常都需要自己的迁移文件。

将多个迁移折叠成一个迁移是一个不好的习惯,在处理不断发展的软件时会陷入困境。您可能不会折叠源控件历史记录,那么为什么要担心数据库架构历史记录?

我唯一可以看到它是合理实用的场合是,如果你要求一个旧项目来创建一个新版本或分拆,并且不希望继续进行大量的迁移。 / p>

答案 5 :(得分:0)

您不应该删除迁移。为什么要创造额外的工作?

迁移本质上是一组指令,用于定义如何构建数据库以支持您的应用程序。在构建应用程序时,迁移会记录您对数据库所做的迭代更改。

恕我直言,通过定期重置基线,您正在进行可能会导致应用程序出现错误/问题的更改,从而创建额外的工作。

如果错误地添加了一个列,然后需要在以后删除,只需创建一个新的迁移以删除多余的列。我的主要原因是,在团队中工作时,您不希望您的同事不得不从头开始重建他们的数据库。通过这种简单的方法,您(和他们)可以以迭代的方式继续工作。

暂时不说 - 从头开始​​构建新数据库(没有任何数据)时,迁移往往会很快运行。我目前正在处理的项目有177个迁移,这在构建新数据库时不会产生任何问题。