我想从我的Rails应用程序中将几千条记录批量插入数据库(在我的情况下为POSTGRES).
这样做的"Rails方式"是什么?一些快速且正确的方法.
我知道我可以通过字符串连接属性来创建SQL查询,但我想要一个更好的方法.
ruby activerecord ruby-on-rails ruby-on-rails-3 rails-postgresql
我需要将一组电子邮件作为不同的记录插入到我的联系人表中.如何才能做到这一点.
Eg: @email = ["a@b.com", "c@d.com", "e@f.com", ... ]
Run Code Online (Sandbox Code Playgroud)
我不想用.
@email.each do |email|
@contact = Contact.new
@contact.email = email
@contact.save
end
Run Code Online (Sandbox Code Playgroud)
这导致n插入quires.我只需要一个插入查询来插入这些值.如何在rails 3.0.9(以及理想的MySQL)中完成.请帮忙
在我们的Rails 3.2.13应用程序(Heroku中的Ruby 2.0.0 + Postgres)中,我们经常从API中检索大量订单数据,然后我们需要更新或创建数据库中的每个订单,以及关联.单个订单创建/更新自身加上约.10-15个关联对象,我们一次最多导入500个订单.
下面的代码可行,但问题是它在速度方面根本没有效率.创建/更新500条记录大约需要 1分钟,生成6500多个db查询!
def add_details(shop, shopify_orders)
shopify_orders.each do |shopify_order|
order = Order.where(:order_id => shopify_order.id.to_s, :shop_id => shop.id).first_or_create
order.update_details(order,shopify_order,shop) #This calls update_attributes for the Order
ShippingLine.add_details(order, shopify_order.shipping_lines)
LineItem.add_details(order, shopify_order.line_items)
Taxline.add_details(order, shopify_order.tax_lines)
Fulfillment.add_details(order, shopify_order.fulfillments)
Note.add_details(order, shopify_order.note_attributes)
Discount.add_details(order, shopify_order.discount_codes)
billing_address = shopify_order.billing_address rescue nil
if !billing_address.blank?
BillingAddress.add_details(order, billing_address)
end
shipping_address = shopify_order.shipping_address rescue nil
if !shipping_address.blank?
ShippingAddress.add_details(order, shipping_address)
end
payment_details = shopify_order.payment_details rescue nil
if !payment_details.blank?
PaymentDetail.add_details(order, payment_details)
end
end
end
def update_details(order,shopify_order,shop)
order.update_attributes(
:order_name => shopify_order.name,
:order_created_at => …Run Code Online (Sandbox Code Playgroud) 我最近开始咨询和帮助开发Rails应用程序,该应用程序使用MongoDB(以Mongoid作为其数据库客户端)来存储其所有模型实例。
在应用程序处于早期启动阶段时就很好了,但是随着应用程序拥有越来越多的客户端,并且开始需要越来越复杂的查询以在界面中显示适当的统计信息和其他信息,我们决定了唯一可行的解决方案前进的是对数据进行规范化,然后转移到结构化数据库。
因此,我们现在正在将表和数据从MongoDB(以Mongoid作为对象映射器)迁移到Postgres(以ActiveRecord作为对象映射器)。因为我们必须确保Mongo数据库中没有不正确的非标准化数据,所以我们必须在Rails-land内部运行这些数据迁移,以确保正在运行验证,回调和健全性检查。
一切都在开发中进行了“细化”,但现在我们正在带有实际生产数据库的登台服务器上运行迁移。事实证明,对于某些迁移,服务器的内存使用量会随着模型实例数量的增加而线性增加,一旦我们填满16 GB的RAM(以及另外16GB的交换空间...),就会导致迁移被终止。
由于我们逐个迁移模型实例,因此我们希望能够找到一种方法来确保内存使用保持不变(接近)。
当前可能导致这种情况的原因是(a)ActiveRecord或Mongoid保持对我们已经导入的对象实例的引用,以及(b)迁移在单个DB事务中运行,因此Postgres占用了越来越多的内存直到完成为止?
所以我的问题是:
这些数据迁移具有以下格式:
class MigrateSomeThing < ActiveRecord::Migration[5.2]
def up
Mongodb::ModelName.all.each do |old_thing| # Mongoid's #.all.each works with batches, see /sf/ask/492885711/
create_thing(old_thing, Postgres::ModelName.new)
end
raise "Not all rows could be imported" if MongoDB::ModelName.count != Postgres::ModelName.count
end
def down
Postgres::ModelName.delete_all
end
def create_thing(old_thing, new_thing)
attrs = old_thing.attributes
# ... maybe alter the attributes slightly to fit Postgres depending on the thing.
new_thing.attributes = attrs
new_thing.save!
end
end
Run Code Online (Sandbox Code Playgroud) Rails版本: 4.2.7
Ruby版本: 2.3.3
我正在运行rake任务,将数百万个对象从CSV和JSON文件格式迁移到我的postgres数据库中.
我试图利用activerecord-import加速将对象写入数据库.
尽可能简化代码,前半部分处理对象类型1(来自一种数据类型),后半部分处理对象类型2.
第一个对象类型迭代如此(为问题简化):
importing_object_one_array = []
my_external_data.each do |element|
new_element = ObjectOne.new(
title: element[0],
body: element[1]
)
importing_object_one_array << new_element
end
ObjectOne.import importing_object_one_array, validate: false
Run Code Online (Sandbox Code Playgroud)
这个大约有250,000个对象运行,写的没有任何问题,我在控制台中进行了检查,并成功编写了对象.
但是,对象类型2具有相当多的额外对象,每个对象的大小和设计大致与对象类型1相同.
其中大约有4,040,000个.
我应该等多久ObjectTwo.import才能跑?我们现在已经好几个小时了.
或者,从调试的角度来看(因为我真的不想重新运行这个rake任务,除非我绝对不得不这样做),有什么脚本或策略可以看看当前是否ObjectTwo.import真的在运行(即使它正在运行)或者任务挂?
我检查了rails控制台,我们看起来仍然ObjectTwo和以前一样在数据库中.
我唯一的另一个想法是,因为我没有在运行之前打印到控制台#import(例如puts "Now starting import!"),我没有100%证明阵列中构建的对象已经完成.