简体   繁体   English

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

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

Problem: I'm creating a Rails app, single dev, running staged/prod servers on Heroku, not publicly released yet.问题:我正在创建一个 Rails 应用程序,单一开发,在 Heroku 上运行暂存/生产服务器,尚未公开发布。 Reworking my DB infrastructure, since I've done several migrations since creating tables.重做我的数据库基础设施,因为自创建表以来我已经进行了几次迁移。 I know it's somewhat trivial, but I'm trying to get things cleaned up before initial launch:我知道这有点微不足道,但我正试图在首次发布之前清理干净:

  1. Redo indexes.重做索引。
  2. Reorder/rename fields.重新排序/重命名字段。 I would prefer avoiding tables with timestamp fields randomly sandwiched in the middle and PostgreSQL doesn't allow simple field reordering (for this reason, I may standardize timestamps as the first fields moving forward, so future migrations aren't so noticeable).我宁愿避免将时间戳字段随机夹在中间的表格,并且 PostgreSQL 不允许简单的字段重新排序(因此,我可能会将时间戳标准化为向前移动的第一个字段,因此未来的迁移并不那么明显)。

Possible Solution(s): I'll need to drop my schema and reload a clean copy of it.可能的解决方案:我需要删除我的架构并重新加载它的干净副本。 I can:我可以:

  1. Edit schema.rb structure for existing tables to my liking.根据我的喜好编辑现有表的schema.rb结构。
  2. (?) Manually edit the [VERSION] timestamp in schema.rb . (?) 手动编辑schema.rb中的[VERSION]时间戳。
  3. (?) Edit latest migration file, duplicate schema.rb . (?) 编辑最新的迁移文件,复制schema.rb
  4. Run rails db:schema:load -esque (likely with additional db:reset -esque steps to drop the existing schema/structure first).运行rails db:schema:load -esque (可能使用额外的db:reset -esque 步骤首先删除现有模式/结构)。
  5. Delete older migration files.删除旧的迁移文件。

Question #1: See 2.-3.问题 #1:见 2.-3。 Aside from the elephant in the room that this method isn't generally recommended long-term, when does rails db:schema:dump have a use case?除了房间里的大象通常不建议长期使用这种方法之外, rails db:schema:dump什么时候有用例? , since it's essentially what I'm doing by hand? ,因为它本质上是我手工做的? I don't believe it would generate models tables not generated through Rails beforehand, so that could get messy (without running rails generate model --skip-migration ).我不相信它会生成事先没有通过 Rails 生成的模型表,因此可能会变得混乱(没有运行rails generate model --skip-migration )。 Does it create a new migration, or at minimum does it update the schema.rb timestamp so as not to look backwards at prior migrations?它是创建一个新的迁移,还是至少更新schema.rb时间戳,以免向后看之前的迁移? Otherwise, I would think :dump would be unconventional to Rails' own system.否则,我会认为:dump对 Rails 自己的系统来说是非常规的。

Question #2: I know it will break staged/production servers once I push the changes (again, I'll have to run step 5. on them or just replace my Heroku apps with fresh copies).问题 #2:我知道一旦我推送更改,它会破坏暂存/生产服务器(同样,我必须在它们上运行第 5 步,或者只是用新副本替换我的 Heroku 应用程序)。 However, would this method also break these too, and/or break future Rails migration steps?但是,这种方法也会破坏这些,和/或破坏未来的 Rails 迁移步骤吗? I'd rather make sure whatever I build can be launched cleanly without requiring additional steps by hand that I could have avoided.我宁愿确保我构建的任何东西都可以干净地启动,而不需要我可以避免的额外步骤。

As someone who as ditched old, embarrassing migrations for a flat, updated schema part way through an app development process, I only ever regretted it .作为一个在应用程序开发过程中放弃旧的、令人尴尬的迁移,转而采用扁平、更新的架构的人,我只后悔过

Migrations only run on deployment, so there's no real speed reason to squash them, combine them, rename them, or remove them (unless you are totally ditching whatever is in that migration).迁移仅在部署时运行,因此没有真正的速度理由来压缩它们、组合它们、重命名它们或删除它们(除非您完全放弃该迁移中的任何内容)。

AND , ALL your migrations only run once on your first deploy.而且您的所有迁移仅在您第一次部署时运行一次。 From then on, only future migrations will be run.从那时起,将只运行未来的迁移。 So the overhead is a one-time thing.所以开销是一次性的。

Having a few (hundred) migration files is really no big deal.拥有几个(数百个)迁移文件真的没什么大不了的。

"But what about the fact that migration #3 adds a column which is later removed by migration #45?" “但是迁移 #3 添加了一个列,该列后来被迁移 #45 删除了呢?” That's how we write software: over time, with changes.这就是我们编写软件的方式:随着时间的推移,随着变化。 It's fine.没关系。

If you need to redo indexes and rename fields , write another migration.如果您需要重做索引重命名字段,请编写另一个迁移。 Call it "CleanupBeforeProductionDeploy" if it'll give you that wonderful sense of cleaned up code.如果它能给你清理代码的美妙感觉,就称它为“CleanupBeforeProductionDeploy”。

Reordering columns is useless.重新排序列是没有用的。 This isn't Excel.这不是 Excel。 Don't bother.不要打扰。

If you need to display fields in a certain order, use SQL or .map or .pluck or I'm sure a dozen other Ruby or RoR solutions, that's what they are for.如果您需要按特定顺序显示字段,请使用 SQL 或.map.pluck或者我敢肯定还有十几个其他 Ruby 或 RoR 解决方案,它们是什么。

You've done good work, it sounds like your app is nearly ready to deploy.您做得很好,听起来您的应用程序几乎可以部署了。 Congratulations, that's a serious milestone.恭喜,这是一个重要的里程碑。 So many of us start scratching something out and never push it across the finish line.我们中的许多人开始抓起一些东西,从不把它推过终点线。 Seriously, you should feel good.说真的,你应该感觉很好。

Don't procrastinate with meaningless fussing that will just lead to errors.不要拖延只会导致错误的无意义的大惊小怪。

Go push the code and be happy. Go 推送代码,开心就好。


Rant over.吐槽一下。 If I haven't convinced you, here are some tips to at least keep you safe / sane.如果我还没有说服你,这里有一些提示至少可以让你保持安全/理智。

The purpose of the schema is a shortcut for creating a new dB from scratch and just jumping to the end without running every migration.模式的目的是从头开始创建新的 dB 并直接跳到最后而不运行每次迁移的捷径。

The schema dump is used, for example, by Heroku when you are creating a backup of your production database.例如,当您创建生产数据库的备份时,Heroku 会使用模式转储

(Just an aside, I use parity to get production data from my apps into my development environments so I can work with "real" data). (顺便说一句,我使用parity将生产数据从我的应用程序获取到我的开发环境中,以便我可以使用“真实”数据)。

You could also use a schema dump from the actual database to create a new schema file if something happened to your schema file.如果您的架构文件发生问题,您还可以使用来自实际数据库的架构转储来创建一个新的架构文件。

So, you can do this, even though you shouldn't waste your time .所以,你可以这样做,即使你不应该浪费你的时间

Here would be my order of operations:这是我的操作顺序:

  1. Keep writing migrations for all these changes you want to make.继续为您想要进行的所有这些更改编写迁移。 Yes, write one or more migrations to make all your changes.是的,编写一个或多个迁移来进行所有更改。 Seriously.严重地。 Let Rails handle versioning and timestamping your schema file as you go.让 Rails 像 go 一样处理模式文件的版本控制和时间戳。 And, this way you can do this in stages and test things out.而且,通过这种方式,您可以分阶段执行此操作并进行测试。

  2. For changing your table column orders I'd do the following, it's messy, but it would work:为了更改您的表格列顺序,我会执行以下操作,这很混乱,但它会起作用:

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?

Use SQL to map and copy the contents of users_disorganized into users.使用 SQL 到map 并将 users_disorganized的内容复制到 users 中。

Here's a good SO post on the topic of SQL inside migrations这是关于迁移中 SQL 主题的好帖子

SQL is really your only choice here since you don't have an ApplicationRecord Model for UserDisorganized. SQL 确实是您唯一的选择,因为您没有用于 UserDisorganized 的 ApplicationRecord Model。

Could you make a UserDisorganized model just to make copying the files over easier?您能否制作一个 UserDisorganized model 只是为了让复制文件更容易? Yes, then you'd have to remember delete that file after your production deploy.是的,那么您必须记住在生产部署后删除该文件。

Starting to see how time-intensive this is going to be?开始看到这将是多么耗时?

Now repeat this process for every table where you want to reorder columns.现在对要对列重新排序的每个表重复此过程。

  1. Once you are all done writing migrations, your pristine schema now has the latest timestamp and version and everything so don't mess with these values .一旦你完成了迁移的编写,你的原始模式现在有最新的时间戳和版本,所以不要弄乱这些值

(you can change them, it'll probably be fine, but if you decide to set them too far in the future... then forget about doing that... then write a small migration just to patch a bug or add a feature... then try to run that migration... then spend 4 hours trying to figure out why nothing happens when you run rake db:migrate ... all just to realize the schema timestamp is later than your migration timestamp... and so on) (您可以更改它们,它可能会很好,但是如果您决定将来将它们设置得太远......然后忘记这样做......然后编写一个小的迁移只是为了修补错误或添加功能...然后尝试运行该迁移...然后花 4 个小时试图弄清楚为什么在运行rake db:migrate时什么都没有发生...所有只是为了意识到架构时间戳晚于您的迁移时间戳...和很快)

  1. Now you can gulp delete all your migrations.现在您可以gulp删除所有迁移。 Yeah.是的。 You don't want them?你不想要他们? Here's your chance to prove it.这是你证明它的机会。 You still serious about this?你还是认真的吗?

  2. How do you then initialize your production database?然后如何初始化生产数据库? Tell Heroku to run rake db:schema:load instead of rake db:migrate .告诉 Heroku 运行rake db:schema:load而不是rake db:migrate

Good luck.祝你好运。

(and don't bother) (不要打扰)

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

相关问题 我如何告诉我的rails程序在生产中运行? - How do i tell my rails program to run on production? Rails 4 - 如何优化Heroku生产环境? - Rails 4 - How do I optimize my Heroku production environment? 如何将数据从生产数据库迁移到开发数据库(第4条)? - How do I migrate data from production db to development db (Rails 4)? 如何最轻松地从XLS导入我的Rails应用数据库? - How do I most easily import from XLS into my rails app database? 如何在Rails测试中使用参数轻松解析URL? - How do I easily parse a URL with parameters in a Rails test? 在Rails开发环境中运行时,如何防止我的“生产”组被调用? - How do I prevent my “production” group from being called when running in my Rails development enviornment? 如何在Rails 3中仅将一张表从开发数据库推送到生产数据库 - How do I push only one table from my development database to my production database in rails 3 Rails如何在未实例化的情况下检查类的存在性? - Rails how do I check for existance of a class when not instantiated yet? 我如何 select 尚未保存在 Rails 中的关联记录? - How do i select an association record that has yet to be saved in Rails? 如何在生产环境中自动启动Rails Background Worker - How do I start my Rails Background Worker automatically in Production Environment
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM