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

发布于 2024-08-06 04:31:15 字数 389 浏览 3 评论 0原文

当我在应用程序*上进行迭代时,我会积累迁移。截至目前,此类文件共有 48 个,涵盖大约 24 个月的活动。

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

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

这看起来明智吗? 如果是这样,这样的练习在什么样的时间间隔才有意义? 如果没有,为什么不呢?

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

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

As I move through the iterations on my application*(s) I accumulate migrations. As of just now there are 48 such files, spanning about 24 months' activity.

I'm considering taking my current schema.rb and making that the baseline.

I'm also considering deleting (subject to source control, of course) the existing migrations and creating a nice shiny new single migration from my my current schema? Migrations tend to like symbols, but rake db:schema:dump uses strings: should I care?

Does that seem sensible?
If so, at what sort of interval would such an exercise make sense?
If not, why not?

And am I missing some (rake?) task that would do this for me?

* In my case, all apps are Rails-based, but anything that uses ActiveRecord migrations would seem to fit the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

心病无药医 2024-08-13 04:31:15

是的,这是有道理的。有合并迁移的做法。为此,只需将当前架构复制到迁移中,然后删除所有早期的迁移即可。这样您就可以管理更少的文件,并且测试可以运行得更快。 您需要小心执行此操作,特别是当您在生产环境中自动运行迁移时。我通常会用新的架构替换我知道每个人都运行过的迁移。

其他人的方法略有不同。

我通常在迁移超过 100 次之前才这样做,但我们可以在开发几个月后实现这一目标。不过,随着项目的成熟,迁移的频率会越来越少,因此您可能不必再次进行迁移。

这确实违背了最佳实践:一旦您签入到源代码管理的迁移,就不要更改它。如果其中存在错误,我会罕见地例外,但这种情况非常罕见(可能是百分之一)。原因是,一旦它们在野外,可能就会有人运行它们。它们在数据库中记录为已完成。如果您更改它们并签入新版本,其他人将无法从更改中受益。您可以要求人们回滚某些更改并重新运行它们,但这违背了自动化的目的。经常这样做,就会变得一团糟。最好还是别管。

Yes, this makes sense. There is a practice of consolidating migrations. To do this, simply copy the current schema into a migration, and delete all the earlier migrations. Then you have fewer files to manage, and the tests can run faster. You need to be careful doing this, especially if you have migrations running automatically on production. I generally replace a migration that I know everyone has run with the new schema one.

Other people have slightly different ways to do this.

I generally haven't done this until we had over 100 migrations, but we can hit this after a few months of development. As the project matures, though, migrations come less and less often, so you may not have to do it again.

This does go against a best practice: Once you check in a migration to source control, don't alter it. I make a rare exception if there is a bug in one, but this is quite rare (1 in 100 maybe). The reason is that once they are out in the wild, some people may have run them. They are recorded as being completed in the db. If you change them and check in a new version, other people will not get the benefit of the change. You can ask people to roll back certain changes, and re-run them, but that defeats the purpose of the automation. Done often, it becomes a mess. It's better left alone.

爱冒险 2024-08-13 04:31:15

我认为有两种迁移:

  • 您在设计/开发期间进行的迁移,因为您改变了对数据库应该是什么样子的想法;

  • 您在版本之间所做的,反映了一些行为更改。

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

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

我读过使用字符串的另一点:“ruby 符号是内存泄漏”,这意味着,当您创建一个符号时,它在整个应用程序生命周期内永远不会被释放。这对我来说似乎毫无意义,因为所有数据库列都将用作 Rails(和 ActiveRecord)应用程序中的符号;迁移任务也不会永远持续下去,所以我认为这一点实际上没有意义。

I think that there are two kinds of migrations:

  • those you made during design/development, because you changed your mind on how your db should be like;

  • those you made between releases, reflecting some behaviour changes.

I get rid of the first kind of migrations as soon as I can, as they do not really represent working releases, and keep the second kind, so that it is possible, in theory, to update the app.

About symbols vs strings: many argue that only strings should be used in migrations: symbols are meant to be "handles" to objects, and should not be used to represent names (column and table names, in this case). This is a mere stylistic consideration, but convinced me, and I'm no more using symbols in migrations.

I've read of another point for using strings: "ruby symbols are memory leaks", meaning that, when you create a symbol, it never gets disposed for all the application life time. This seems quite pointless to me, as all your db columns will be used as symbols in a Rails (and ActiveRecord) app; the migrating task, also, will not last forever, so I don't think that this point actually makes sense.

盛夏已如深秋| 2024-08-13 04:31:15

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] 上面所说的关于不同目的的不同迁移的内容。我建议清理面向开发的迁移以及在分支发布时执行的其他任务。这对我、我自己和小团队来说都很有效。当然,我的主应用程序位于其他两个数据库之上和之间,它们具有自己的架构,我必须小心,因此我们使用迁移(而不是架构恢复)进行新安装,并且这些数据库需要在发布工程中生存。

The top of schema.rb declares:

# 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.

I must endorse what [giorgian] said above about different migrations for different purposes. I recommend cleaning up development-oriented migrations along with other tasks you do when you branch for a release. That works for well for me, for myself and small teams. Of course my main app sits atop and between two other databases with their own schemas which I have to be careful of so we use migrations (rather than schema restore) for a new install and those need to survive release engineering.

毅然前行 2024-08-13 04:31:15

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

如果你真的想快速启动并运行一个新数据库,你可以使用 rake db:schema:load RAILS_ENV=your_environment 加载模式,如果你想快速设置测试数据库,你可以使用 rake db:test:prepare

话虽这么说,如果您确实想合并迁移,那么我会创建一个新的迁移,检查您集中的最后一次迁移是否已执行(例如:您添加的列是否存在?),如果不存在,然后它就会着火。否则,迁移将在完成时将其自身添加到架构表中,这样它就不会再次尝试触发。

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

Having lots of migrations are a good thing. Combined with your version control system, they allow you to see what developer made a change to the database and why. This helps with accountability. Removing them just makes this a big hassle.

If you really want to get a new database up and running quickly you can just load the schema with rake db:schema:load RAILS_ENV=your_environment and if you want to get your test database setup quick you can just use rake db:test:prepare

That being said, if you really want to consolidate your migrations then I'd create a new migration that checks to see if the very last migration in your set has been performed (ex: does the column you added exist?) and if not, then it will fire. Otherwise the migration will just add itself to the schema table as completed so it doesn't attempt to fire again.

Just communicate what you're doing to the rest of your team so that they understand what is going on lest they blindly fire off a rake db:migrate and screw up something they already had.

清音悠歌 2024-08-13 04:31:15

尽管我确信每个人都有自己的做法,但迁移系统的工作方式隐含了一些规则:

  • 切勿对可能已被其他开发人员或以前的部署使用的迁移提交更改。相反,进行额外的迁移以根据需要进行调整。
  • 切勿将模型级依赖项放入迁移中。该模型可能会在将来的某个时候被重命名或删除,这将阻止迁移。保持迁移尽可能独立,即使这意味着它非常简单且低级别。

当然也有例外。例如,如果由于某种原因迁移不起作用,则可能需要打补丁才能使其更新。但即便如此,迁移带来的变化的性质也不应该改变,尽管它们的实施可能会改变。

任何成熟的 Rails 项目都可能有大约 200 到 1000 次迁移。根据我的经验,除非处于规划阶段,否则很少有项目少于 30 个。毕竟,每个模型通常都需要自己的迁移文件。

在开发不断发展的软件时,将多个迁移合并为一个迁移是一种坏习惯。您可能不会折叠源代码管理历史记录,那么为什么要担心数据库架构历史记录呢?

我认为它相当实用的唯一情况是,如果您要分叉一个旧项目来创建新版本或衍生产品,并且不想继续进行大量迁移。

Although I'm sure everyone has their own practices, there's a few rules implied by the way the migration system works:

  • Never commit changes to migrations that may have been used by other developers or previous deployments. Instead, make an additional migration to adjust things as required.
  • Never put model-level dependencies in a migration. The model may be renamed or deleted at some point in the future and this would prevent the migration. Keep the migration as self-contained as possible, even if that means it's quite simplistic and low-level.

Of course there are exceptions. For example, if a migration doesn't work, for whatever reason, a patch may be required to bring it up to date. Even then, though, the nature of the changes effected by the migration shouldn't change, though the implementation of them may.

Any mature Rails project will likely have around 200 to 1000 migrations. In my experience it is unusual to see a project with less than 30 except in the planning stages. Each model, after all, typically needs its own migration file.

Collapsing multiple migrations into a single one is a bad habit to get into when working on an evolving piece of software. You probably don't collapse your source control history, so why worry about database schema history?

The only occasion I can see it as being reasonably practical is if you're forking an old project to create a new version or spin-off and don't want to have to carry forward with an extraordinary number of migrations.

垂暮老矣 2024-08-13 04:31:15

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

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

恕我直言,通过定期重置基线,您所做的更改可能会给您的应用程序带来错误/问题,从而产生额外的工作。

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

顺便说一句 - 当从头开始构建新数据库(没有任何数据)时,迁移往往运行得非常快。我目前正在进行的一个项目有 177 次迁移,这在构建新数据库时不会出现问题。

You shouldn't be deleting migrations. Why create the extra work?

Migrations essentially are a set of instructions that define how to build the database to support your application. As you build your application the migrations record the iterative changes you make to the database.

IMHO by resetting the baseline periodically you are making changes that have the potential to introduce bugs/issues with your application, creating extra work.

In the case where a column is mistakenly added and then needs to be removed sometime later, just create a new migration to remove extra column. My main reason for this is that when working in a team you don't want your colleagues to have to keep rebuilding their databases from scratch. With this simple approach you (and they) can carry on working in an iterative manner.

As an aside - when building a new database from scratch (without any data) migrations tend to run very quickly. A project I am currently working on has 177 migrations, this causes no problems when building a new database.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文