问题
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