【问题标题】:How do I easily restructure my Rails' DB not yet in production?如何轻松重组尚未投入生产的 Rails\' DB?
【发布时间】:2022-08-16 11:12:42
【问题描述】:

问题:我正在创建一个 Rails 应用程序,单一开发,在 Heroku 上运行分阶段/生产服务器,尚未公开发布。重做我的数据库基础设施,因为自创建表以来我已经完成了几次迁移。我知道这有点微不足道,但我试图在首次发布之前清理干净:

  1. 重做索引。
  2. 重新排序/重命名字段。我宁愿避免将时间戳字段随机夹在中间的表,并且 PostgreSQL 不允许简单的字段重新排序(因此,我可能会将时间戳标准化为向前移动的第一个字段,因此未来的迁移不会那么明显)。

    可能的解决方案):我需要删除我的架构并重新加载它的干净副本。我可以:

    1. 根据我的喜好编辑现有表的schema.rb 结构。
    2. (?) 在schema.rb 中手动编辑[VERSION] 时间戳。
    3. (?) 编辑最新的迁移文件,复制schema.rb
    4. 运行rails db:schema:load-esque(可能需要额外的db:reset-esque 步骤来首先删除现有架构/结构)。
    5. 删除旧的迁移文件。

      问题一:见 2.-3。除了房间里的大象,这种方法一般不推荐长期使用,rails db:schema:dump 什么时候有用例?,因为它本质上是我手工做的?我不相信它会生成不是事先通过 Rails 生成的模型表,因此可能会变得混乱(不运行 rails generate model --skip-migration)。它是创建一个新的迁移,还是至少更新schema.rb 时间戳,以免向后看之前的迁移?否则,我会认为:dump 对 Rails 自己的系统来说是非常规的。

      问题2:我知道一旦我推送更改,它将破坏分阶段/生产服务器(再次,我必须在它们上运行第 5 步,或者只是用新副本替换我的 Heroku 应用程序)。然而,这种方法也会破坏这些,和/或破坏未来的 Rails 迁移步骤吗?我宁愿确保我构建的任何东西都可以干净地启动,而不需要我可以避免的额外步骤。

  • 您关心数据库中的任何数据吗?
  • @muistooshort,还没有。

标签: ruby-on-rails postgresql database-design rake ruby-on-rails-7


【解决方案1】:

作为一个在应用程序开发过程中放弃旧的、令人尴尬的迁移,转而采用扁平、更新的架构的人,我只后悔过.

迁移仅在部署时运行,因此没有真正的速度理由来压缩它们、组合它们、重命名它们或删除它们(除非您完全放弃该迁移中的任何内容)。

, 您的所有迁移仅在您第一次部署时运行一次。从那时起,将只运行未来的迁移。所以开销是一次性的。

拥有几个(数百个)迁移文件真的没什么大不了的。

“但是迁移 #3 添加了一个列,该列后来被迁移 #45 删除了呢?”这就是我们编写软件的方式:随着时间的推移,随着变化。没关系。

如果你需要重做索引重命名字段,写另一个迁移。如果它能给你清理代码的美妙感觉,就称它为“CleanupBeforeProductionDeploy”。

重新排序列没用。这不是 Excel。不要打扰。

如果您需要按特定顺序显示字段,请使用 SQL 或 .map.pluck 或者我敢肯定还有十几种其他 Ruby 或 RoR 解决方案,这就是它们的用途。

您做得很好,听起来您的应用程序几乎可以部署了。恭喜,这是一个重要的里程碑。我们中的许多人开始抓挠一些东西绝不把它推过终点线。说真的,你应该感觉很好。

不要拖延只会导致错误的无意义的大惊小怪。

去推送代码并快乐。


吐槽一下。如果我还没有说服你,这里有一些提示至少可以让你保持安全/理智。

的目的图式是从头开始创建新 dB 并直接跳到最后而不运行每次迁移的捷径。

模式转储例如,当您创建生产数据库的备份时,Heroku 会使用它。

(顺便说一句,我使用parity 将生产数据从我的应用程序获取到我的开发环境中,以便我可以使用“真实”数据)。

如果您的架构文件发生问题,您还可以使用来自实际数据库的架构转储来创建新的架构文件。

那么你能够这样做,即使你不应该浪费你的时间.

这是我的操作顺序:

  1. 继续为您想要进行的所有这些更改编写迁移。是的,编写一个或多个迁移来进行所有更改。严重地。让 Rails 随时处理模式文件的版本控制和时间戳。而且,通过这种方式,您可以分阶段执行此操作并进行测试。

  2. 为了更改您的表格列顺序,我会执行以下操作,这很混乱,但它会起作用:

    rename_table :users, :users_disorganized
    
    create_table :users do |t|
      ...
    end
    
    # write some complicated SQL to copy 'users_disorganized' data into 'users'
    
    # safety catch in case copying things over didn't work
    drop_table :users_disorganized unless User.all.size.zero?
    

    使用SQL 将map and copyusers_disorganized 的内容整理成users。

    这是a good SO post on the topic of SQL inside migrations

    SQL 确实是您唯一的选择,因为您没有用于 UserDisorganized 的 ApplicationRecord 模型。

    您能否制作一个 UserDisorganized 模型只是为了更轻松地复制文件?是的,那么您必须记住在生产部署后删除该文件。

    开始看到这将是多么耗时?

    现在重复这个过程每一个要对列重新排序的表。

    1. 一旦你完成了迁移的编写,你的原始模式现在有最新的时间戳和版本,一切都如此不要乱用这些值.

    (您可以更改它们,它可能会很好,但是如果您决定将来将它们设置得太远......然后忘记这样做......然后编写一个小的迁移只是为了修补错误或添加功能...然后尝试运行该迁移...然后花 4 小时试图弄清楚为什么在运行 rake db:migrate 时什么都没有发生...所有只是为了意识到架构时间戳晚于您的迁移时间戳...等等上)

    1. 现在你可以吞咽删除所有迁移。是的。你不想要他们?这是你证明它的机会。你还是认真的吗?

    2. 然后如何初始化生产数据库?告诉 Heroku 运行 rake db:schema:load 而不是 rake db:migrate

    祝你好运。

    (不要打扰)

【讨论】:

    猜你喜欢
    • 2019-06-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2015-01-18
    • 1970-01-01
    • 2014-11-27
    • 2014-07-13
    相关资源
    最近更新 更多