ruby-on-rails - रेल पर रूबी - एक CSV फ़ाइल से डेटा आयात करें




6 Answers

require 'csv'    

csv_text = File.read('...')
csv = CSV.parse(csv_text, :headers => true)
csv.each do |row|
  Moulding.create!(row.to_hash)
end

मैं एक CSV फ़ाइल से डेटा को मौजूदा डेटाबेस तालिका में आयात करना चाहता हूं। मैं सीएसवी फ़ाइल को सहेजना नहीं चाहता हूं, बस उस से डेटा लें और इसे मौजूदा तालिका में डाल दें। मैं रुबी 1.9.2 और रेल 3 का उपयोग कर रहा हूं।

यह मेरी मेज है:

create_table "mouldings", :force => true do |t|
  t.string   "suppliers_code"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "name"
  t.integer  "supplier_id"
  t.decimal  "length",         :precision => 3, :scale => 2
  t.decimal  "cost",           :precision => 4, :scale => 2
  t.integer  "width"
  t.integer  "depth"
end

क्या आप मुझे ऐसा करने के लिए सबसे अच्छा तरीका दिखाने के लिए कुछ कोड दे सकते हैं, धन्यवाद।




smarter_csv मणि विशेष रूप से इस उपयोग-मामले के लिए बनाया गया था: CSV फ़ाइल से डेटा पढ़ने और जल्दी से डेटाबेस प्रविष्टियां बनाने के लिए।

  require 'smarter_csv'
  options = {}
  SmarterCSV.process('input_file.csv', options) do |chunk|
    chunk.each do |data_hash|
      Moulding.create!( data_hash )
    end
  end

आप एक समय में एन सीएसवी-पंक्तियों को पढ़ने के लिए विकल्प chunk_size का उपयोग कर सकते हैं, और उसके बाद जॉब्स उत्पन्न करने के लिए आंतरिक लूप में chunk_size का उपयोग कर सकते हैं जो उन्हें तुरंत बनाने के बजाय नए रिकॉर्ड बनाएंगे - इस तरह आप उत्पन्न करने के भार को फैला सकते हैं कई श्रमिकों के लिए प्रविष्टियां।

यह भी देखें: https://github.com/tilo/smarter_csv




आप Upsert प्रयास कर Upsert :

require 'upsert' # add this to your Gemfile
require 'csv'    

u = Upsert.new Moulding.connection, Moulding.table_name
CSV.foreach(file, headers: true) do |row|
  selector = { name: row['name'] } # this treats "name" as the primary key and prevents the creation of duplicates by name
  setter = row.to_hash
  u.row selector, setter
end

यदि आप यही चाहते हैं, तो आप तालिका से स्वत: वृद्धि प्राथमिक कुंजी से छुटकारा पाने और प्राथमिक कुंजी को name सेट करने पर भी विचार कर सकते हैं। वैकल्पिक रूप से, यदि प्राथमिक कुंजी बनाने वाले गुणों का कुछ संयोजन है, तो चयनकर्ता के रूप में इसका उपयोग करें। कोई सूचकांक जरूरी नहीं है, यह सिर्फ इसे तेज कर देगा।




इस मणि का प्रयोग करें: https://rubygems.org/gems/active_record_importer

class Moulding < ActiveRecord::Base
  acts_as_importable
end

तो अब आप इसका उपयोग कर सकते हैं:

Moulding.import!(file: File.open(PATH_TO_FILE))

बस यह सुनिश्चित कर लें कि आपके शीर्षलेख आपकी तालिका के कॉलम नाम से मेल खाते हैं




मुझे पता है कि यह पुराना सवाल है लेकिन यह अभी भी Google में पहले 10 लिंक में है।

पंक्तियों को एक-एक करके सहेजना बहुत प्रभावी नहीं है क्योंकि यह लूप में डेटाबेस कॉल का कारण बनता है और आप इससे बेहतर बचते हैं, खासकर जब आपको डेटा के विशाल भाग डालने की आवश्यकता होती है।

बैच डालने का उपयोग करने के लिए यह बेहतर (और काफी तेज़) है।

INSERT INTO `mouldings` (suppliers_code, name, cost)
VALUES
    ('s1', 'supplier1', 1.111), 
    ('s2', 'supplier2', '2.222')

आप मैन्युअल रूप से ऐसी क्वेरी बना सकते हैं और Model.connection.execute(RAW SQL STRING) (अनुशंसित नहीं) की तुलना में या gem activerecord-import (इसे पहली बार 11 अगस्त 2010 को जारी किया गया था) का उपयोग करके इस मामले में केवल सरणी rows में डेटा डालें और Model.import rows करें

विवरण के लिए मणि दस्तावेज़ देखें




यदि आप SmartCSV का उपयोग करना चाहते हैं

all_data = SmarterCSV.process(
             params[:file].tempfile, 
             { 
               :col_sep => "\t", 
               :row_sep => "\n" 
             }
           )

यह प्रत्येक पंक्ति में टैब सीमित डेटा का प्रतिनिधित्व करता है "\t" पंक्तियों के साथ नई लाइनों से अलग "\n"




Related