繁体   English   中英

如何轻松重组尚未投入生产的 Rails 数据库?

[英]How do I easily restructure my Rails' DB not yet in production?

问题:我正在创建一个 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. 删除旧的迁移文件。

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

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

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

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

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

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

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

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

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

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

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

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

Go 推送代码,开心就好。


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

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

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

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

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

所以,你可以这样做,即使你不应该浪费你的时间

这是我的操作顺序:

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

  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 并将 users_disorganized的内容复制到 users 中。

这是关于迁移中 SQL 主题的好帖子

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

您能否制作一个 UserDisorganized model 只是为了让复制文件更容易? 是的,那么您必须记住在生产部署后删除该文件。

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

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

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

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

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

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

祝你好运。

(不要打扰)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM