Inserting Multiple Records at a time into Model [duplicate]

北城以北 提交于 2019-12-08 03:17:08

问题


I am looking for some best practices when it comes to inserting data into a model, especially when there are a lot of records to be created, so far I am retrieving some XML and saving it into a model

doc = Nokogiri::XML.parse(open(url))
doc.xpath('//xmlns:feed/xmlns:entry[xmlns:title[node()]]').each do |s|

  cid = s.xpath("xmlns:id").text
  email = s.xpath("gd:email/@address").text
  name = s.xpath("xmlns:title").text

  data = Contact.new(
    :cid => cid,
    :email => email,
    :name => name)
  data.save
end

Now this is inserting the records in one by one which is taking too long in my opinion.

I have read that one solution is to use transactions or I could do a single mass insert? My question is which one would I benefit the most from and how would i re format what i already have to each of these? Seeing an example of my current setup into the new setup would benefit me as I would be able to understand it more and actually learn from it

Any help appreciated

Thanks


回答1:


Someone else has tackled this, and the solution was to use activerecord-import. See original question...

Details on using activerecord-import are on it's wiki

Edit: Apparently the link button won't duplicate the link as title if you don't highlight text.

doc = Nokogiri::XML.parse(open(url))
data = []
doc.xpath('//xmlns:feed/xmlns:entry[xmlns:title[node()]]').each do |s|

  cid = s.xpath("xmlns:id").text
  email = s.xpath("gd:email/@address").text
  name = s.xpath("xmlns:title").text

  data << Contact.new(
    :cid => cid,
    :email => email,
    :name => name)
end
Contact.import data



回答2:


You might also try upsert, which will allow you to insert the records quickly (in some tests, faster than activerecord-import) without first accumulating them in memory:

require 'upsert'
# [...]
doc = Nokogiri::XML.parse(open(url))
Upsert.batch(Contact.connection, Contact.table_name) do |upsert|
  doc.xpath('//xmlns:feed/xmlns:entry[xmlns:title[node()]]').each do |s|
    cid = s.xpath("xmlns:id").text
    email = s.xpath("gd:email/@address").text
    name = s.xpath("xmlns:title").text
    upsert.row(
      :cid => cid,
      :email => email,
      :name => name
    )
  end
end

This works for MySQL, Postgres, and SQLite3.



来源:https://stackoverflow.com/questions/15812377/inserting-multiple-records-at-a-time-into-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!