在 git 中管理 schema.rb 的首选方法是什么?

发布于 2024-07-16 07:07:04 字数 346 浏览 5 评论 0原文

我不想将 schema.rb 添加到 .gitignore,因为我希望能够从该文件加载新的数据库架构。 然而,保持其签入状态会导致各种虚假冲突,这些冲突可以通过新的 db:migrate:reset 轻松解决。

基本上我想要一种方法:

  1. 将 schema.rb 保留在存储库中以进行部署时数据库设置
  2. 将 schema.rb 保留在“.gitignore”中以进行一般开发

将有一两个人负责更新 schema.rb 并知道它是正确的。

有没有办法既能鱼与熊掌兼得呢?

I don't want to add schema.rb to .gitignore, because I want to be able to load a new database schema from that file. However, keeping it checked in is causing all sorts of spurious conflicts that are easily resolved by a fresh db:migrate:reset.

Basically I want a way to:

  1. Keep schema.rb in the repository for deploy-time database setup
  2. Keep schema.rb in '.gitignore' for general development

There would be one or two people responsible for updating schema.rb and knowing that it was correct.

Is there a way I can have my cake and eat it, too?

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

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

发布评论

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

评论(9

当梦初醒 2024-07-23 07:07:04

恐怕您正在寻找的神奇解决方案并不存在。 该文件通常在版本控制中管理,然后对于版本行上的任何冲突,只需选择两个日期中较晚的一个。 只要您还运行所有关联的迁移,就不应该以这种方式失去同步。 如果两个开发人员对 schema.rb 的类似区域进行了修改,并且除了版本之外还出现了冲突,那么您将面临正常的合并冲突解决方案,但在我看来,这些通常很容易理解和解决。 我希望这对一些人有帮助!

I'm afraid the magic solution you're looking for does not exist. This file is normally managed in version control, then for any conflicts on the version line just choose the later of the two dates. As long as you're also running all of the associated migrations nothing should get out of sync this way. If two developers have caused modifications to a similar area of schema.rb and you get conflicts in addition to the version then you are faced with a normal merge conflict resolution, but in my opinion these are normally easy to understand and resolve. I hope this helps some!

只是在用心讲痛 2024-07-23 07:07:04

您可以做的另一件事是使用:

git update-index --assume-unchanged /path/schema.rb

这会将文件保留在存储库中,但不会跟踪更改。 您可以随时使用以下方式切换跟踪:

git update-index --no-assume-unchanged /path/schema.rb

One other thing you can do is use:

git update-index --assume-unchanged /path/schema.rb

This will keep the file in the repository but won't track changes. you can switch the tracking anytime by using:

git update-index --no-assume-unchanged /path/schema.rb
似梦非梦 2024-07-23 07:07:04

对我来说非常有效的方法是删除 .gitignore schema.rb,然后在每个开发人员 rake db:migrate 时重新生成它。

您仍然可以实现您想要的目标,而无需从 0 开始迁移,也无需冒着几年前迁移失败的风险,只需定期“汇总”迁移即可。 您可以通过以下方式执行此操作:

  1. 使用 rake db:migrate 运行所有未完成的迁移
  2. ActiveRecord::Schema.defineschema.rb 的内容code> block
  3. 将其粘贴到 def up 内的initial_schema迁移中(覆盖已有的内容)
  4. 删除所有其他迁移

现在,您的initial_schema迁移是新系统的起点,您不必担心冲突在 schema.rb 中,可能无法正确解析。 这并不神奇,但确实有效。

What has worked really well for me is to delete and .gitignore schema.rb and then have it regenerated for each developer when they rake db:migrate.

You can still achieve what you wanted without migrating from 0 and risking broken migrations from years ago by simply doing a "roll-up" of the migrations periodically. You can do this by:

  1. Run all outstanding migrations with rake db:migrate
  2. Taking the contents of your schema.rb in the ActiveRecord::Schema.define block
  3. Paste it into your initial_schema migration inside def up (overwriting what's already there)
  4. Delete all other migrations

Now your initial_schema migration is your starting point for new systems and you don't have to worry about conflicts in schema.rb that may not be resolved correctly. It's not magical, but it works.

北音执念 2024-07-23 07:07:04

在预提交 git hook 中执行 rake db:dump 就足够了吗?

以下内容不一定会解决(1)或(2),但它可能会解决合并问题,然后(1)和(2)可能会消失。

Would it be sufficient to do a rake db:dump in a pre-commit git hook?

The following won't necessarily fix (1) or (2), but it might take care of the merging issue, and then maybe (1) and (2) go away.

落墨 2024-07-23 07:07:04

不要使用 .gitignore,而是使用单独的分支:Develop,其中省略 schema.rbTest部署,其中包含schema.rb。 仅在开发分支中进行代码更改,切勿从 Test 合并到 Develop。 将 schema.rb 保留在单独的分支中:

Developer A             
    Develop      --------             
    Local Schema          \           Your Repo
    Test                    --------->    Dev A
                            --------->    Dev B
Developer B               /               Master
    Develop      --------                 Schema
    Local Schema                          Test
    Test                                  Deploy

在 Git 中,分支是指向文件内容集合的指针,因此它们可以包含或排除特定文件以及跟踪文件版本。 这使得它们成为构建特定工作流程的灵活工具。

Instead of using .gitignore, use separate branches: Develop which omits schema.rb and Test and Deploy which include schema.rb. Only make code changes in the Develop branches and never merge from Test into Develop. Keep schema.rb in a separate branch:

Developer A             
    Develop      --------             
    Local Schema          \           Your Repo
    Test                    --------->    Dev A
                            --------->    Dev B
Developer B               /               Master
    Develop      --------                 Schema
    Local Schema                          Test
    Test                                  Deploy

In Git, branches are pointers to collections of file contents, so they can include or exclude particular files as well as track file versions. This makes them flexible tools for building your particular workflow.

也只是曾经 2024-07-23 07:07:04

您可以定义合并策略。
我找到了这个解决方案,但不记得来源

[merge "railsschema"]
name = newer Rails schema version
driver = "ruby -e '\n\
    system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n\
    b = File.read(%(%A))\n\
    b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n>+ .*/) do\n\
      %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n\
    end\n\
    File.open(%(%A), %(w)) {|f| f.write(b)}\n\
    exit 1 if b.include?(%(<)*%L)'"

将此放在“某处”并且

git-config --global core.attributesfile "somewhere"

You could define a merge strategy.
I've found this solution, but dont remember the source

[merge "railsschema"]
name = newer Rails schema version
driver = "ruby -e '\n\
    system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n\
    b = File.read(%(%A))\n\
    b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n>+ .*/) do\n\
      %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n\
    end\n\
    File.open(%(%A), %(w)) {|f| f.write(b)}\n\
    exit 1 if b.include?(%(<)*%L)'"

put this "somewhere" and

git-config --global core.attributesfile "somewhere"
可可 2024-07-23 07:07:04

我构建了一个 gem 来解决这个问题。

它对列、索引名称和外键进行排序,删除多余的空格并运行 Rubocop 进行某些格式化以统一 schema.rb 文件的输出。

https://github.com/jakeonrails/fix-db-schema-conflicts

将其添加到 Gemfile 后,您只需像平常一样运行 rake db:migraterake db:schema:dump 即可。

I built a gem to solve this problem.

It sorts columns, index names and foreign keys, removes excess whitespace and runs Rubocop for some formatting to unify the output of your schema.rb file.

https://github.com/jakeonrails/fix-db-schema-conflicts

After you add it to your Gemfile you just run rake db:migrate or rake db:schema:dump like normal.

梦归所梦 2024-07-23 07:07:04
  1. 提交 schema.rb 文件。
  2. 运行 git pull(或继续您正在执行的操作)

每次迁移数据库时,schema.rb 文件都会更新并显示在 git status 中。 当处理某些事情并偶尔执行 git pull 时,这可能会很烦人,因为您必须在拉取之前提交 schema.rb 文件才能解决冲突。 这意味着每次迁移数据库时,都需要提交 schema.rb 文件。

  1. Commit schema.rb file.
  2. Run git pull (or continue with what you're doing)

Every time you migrate the database, the schema.rb file updates and appears in git status. When working on something and occasionally doing git pull, this can be annoying because you have to commit schema.rb file before pulling to resolve conflict. This means that every time you migrate the database, you need to commit schema.rb file.

尘曦 2024-07-23 07:07:04

当然,schema.rb 应该被 Git 跟踪。

我刚刚发布了这个 gem,它可以永久解决分支之间的“冲突”问题。

该宝石的想法很简单。 它将所有已迁移的迁移保留在 tmp 文件夹中,以便 Git 忽略它们。 这只是你当地的故事。 需要这些文件来回滚另一个分支中的“未知”迁移。 现在,每当由于在其他分支中运行迁移而导致数据库架构不一致时,只需在当前分支内运行 rails db:migrate ,它就会自动修复问题。 宝石会自动为您完成所有这些魔法。

schema.rb should be tracked Git, of course.

I've just released this gem that can solve an issue with "conflicts" between branches for good.

The idea of that gem is simple. It keeps all migrated migrations inside tmp folder so that Git ignores them. It's just only your local story. These files are needed to roll back the "unknown" migrations being in another branch. Now, whenever you have an inconsistent DB schema due to running migrations in some other branch just run rails db:migrate inside the current branch and it will fix the issue automatically. The gem does all this magic automatically for you.

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