[英]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:我知道这有点微不足道,但我正试图在首次发布之前清理干净:
Possible Solution(s): I'll need to drop my schema and reload a clean copy of it.可能的解决方案:我需要删除我的架构并重新加载它的干净副本。 I can:我可以:
schema.rb
structure for existing tables to my liking.根据我的喜好编辑现有表的schema.rb
结构。[VERSION]
timestamp in schema.rb
. (?) 手动编辑schema.rb
中的[VERSION]
时间戳。schema.rb
. (?) 编辑最新的迁移文件,复制schema.rb
。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 步骤首先删除现有模式/结构)。 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 .所以,你可以这样做,即使你不应该浪费你的时间。
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.而且,通过这种方式,您可以分阶段执行此操作并进行测试。
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.现在对要对列重新排序的每个表重复此过程。
(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
时什么都没有发生...所有只是为了意识到架构时间戳晚于您的迁移时间戳...和很快)
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?你还是认真的吗?
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.