繁体   English   中英

带有 has_one 的 ActiveRecord 批量插入

[英]ActiveRecord bulk insert with has_one

你有没有解决过用嵌套关联批量插入记录的问题? (使用 rails insert_all 或使用 import gem)示例:

Dog.import!(array_of_dogs)

Dog.insert_all(array_of_dogs)

如果狗的所有者协会为

has_one :owner, class_name: Person

并期望坚持所有的狗和他们的主人。

有一种叫做 DutyFree 的宝石可以让这种事情变得简单。 想象一下,有一个包含三个类别、子类别和餐馆表的模式:

___________     _____________     _____________
|Category |     |Subcategory|     |Restaurant |
|         |     |           |     |           |
|         |---->|belongs_to |---->|belongs_to |
|         |     |   Category|     |Subcategory|
|         |     |           |     |           |
¯¯¯¯¯¯¯¯¯¯¯     ¯¯¯¯¯¯¯¯¯¯¯¯¯     ¯¯¯¯¯¯¯¯¯¯¯¯¯

这个 gem 智能地分析模型上的 has_many 和belongs_to 关联,并根据这些关系确定如何在所有目标表中正确保存每个导入的行。 根据数据是否已经存在来执行创建或更新,并且它是基于每个表的,因此例如如果类别已经存在但子类别或餐厅不存在,那么只有这两个部分是添加并关联到适当的类别。

这个具体的例子可以在这里的测试中看到: https : //github.com/lorint/duty_free/blob/master/spec/models/restaurant_reverse_spec.rb

对于 Dog 和 Person 示例,您需要做的就是将 gem 放入 Gemfile 并打包之后,打开bin/rails c并尝试使用以下命令导出示例:

Person.df_export

它应该会自动通过个人的belongs_to 来找到他们相关的Dog。 (顺便说一下,您可能会考虑切换此关联,以便belongs_to 在Dog 中,而不是has_one 将其转换为has_many,这样一个人就可以拥有许多条狗。但那是另一回事了。如果您要切换它会更有意义做 Dog.df_export 或 Dog.suggest_template。)

如果您想进一步自定义所涉及的列,请让 gem 为您提供一个入门模板,该模板可以通过以下方式直接添加到 Person 模型中:

Person.suggest_template

它显示的 IMPORT_TEMPLATE 哈希包含有关您希望具有唯一性的列的详细信息,例如此人的电子邮件或电话号码,以及可能是狗的生日或其他内容。

希望所有这些都有帮助。

你有两种可能。

  1. 您删除所有约束并插入所有数据并在最后添加约束。 这是有效的,因为在备份时所有约束都起作用并且在恢复后会起作用

  2. 您一次只能插入一个表,因此您创建了数据库的 ER 模型,查看必须先创建哪些表,以便可以使用已创建的合作伙伴表创建上面层次结构中的所有表. 依此类推,直到你到达终点。 ER 模型不是绝对需要的,但在具有大量表的大型数据库中,它有助于保持顺序,并且使用正确的程序,您可以移动表以找到正确的恢复顺序。

您必须单独插入关联。

我已经在我的博客中解释了我如何解决这个问题 - https://medium.com/@muralidharanashish/bulk-import-in-ruby-on-rails-8546fed74f4

暂无
暂无

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

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