[英]Batch processing and error handling in CSV upload in Rails
我正在使用活動管理員,並將記錄從CSV文件上傳到數據庫中。 但是,這里發生兩個問題。 如果缺少任何歸檔文件,則代碼會中斷,其次,性能將達到一周,我們不能在批處理過程中這樣做。 這很重要,我相信許多開發人員都在為這種問題尋求一個好的解決方案。
require 'CSV'
class CsvDb
class << self
def convert_save(model_name, csv_data, field_name=nil)
target_model = model_name.classify.constantize
csv_file = csv_data.read
row_headers={}
counter=0;
#Thread.new do
CSV.parse(csv_file) do |row|
if counter==0
temp=row
row_headers = Hash[temp.map.with_index.to_a]
counter +=1
next
end
unless row[row_headers["name"]].nil?
temp={}
business_type = row[row_headers["business_type_id"]]
business_type_id = business_type=='Online' ? 1: business_type=='Local' ? 2: 3
temp[:business_type_id] = business_type_id
temp[:user_id] = row[row_headers["user_id"]]
temp[:name] = row[row_headers["name"]]
temp[:country_id] = row[row_headers["country_id"]]
temp[:homepage] = row[row_headers["homepage"]] ||=""
temp[:telephone] = row[row_headers["telephone"]] ||=""
temp[:email] = row[row_headers["email"]] ||=""
temp[:address] = row[row_headers["address"]] ||=""
temp[:latitude] = row[row_headers["latitude"]]
temp[:longitude] = row[row_headers["longitude"]]
temp[:facebook] = row[row_headers["facebook"]] ||=""
temp[:twitter] = row[row_headers["twitter"]] ||=""
temp[:google] = row[row_headers["google"]] ||=""
temp[:instagram] = row[row_headers["instagram"]] ||=""
temp[:pinterest] = row[row_headers["pinterest"]] ||=""
temp[:free_shipping] = row[row_headers["free_shipping"]]
temp[:ship_details] = row[row_headers["ship_details"]] ||=""
temp[:category_ids] = [row[row_headers["category_ids"]]]
temp[:style_ids] = [row[row_headers["style_ids"]]]
temp[:shipping_country_ids] = [row[row_headers["shipping_country_ids"]]]
temp[:filter_ids] = [row[row_headers["filter_ids"]]]
business = target_model.new(temp)
business.save
end
end
ActiveRecord::Base.connection.close
end
#end
end
end
我將只關注CSV行到對象的轉換。 除非體內有很多重復。 所有這些行都應該被提及一次,然后循環處理,而不是像這樣硬編碼它們。 例如
unless row[row_headers["name"]].nil?
temp={}
business_type = row[row_headers["business_type_id"]]
business_type_id = business_type == "Online" ? 1: business_type == "Local" ? 2 : 3
temp[:business_type_id] = business_type_id
for name in [:user_id, :name, :country_id, :latitude, :longitude, :free_shipping, :category_ids, :style_ids, :shipping_country_ids]
temp[name] = row[row_headers[name.to_s]]
end
for name in [:homepage, :telephone, :email, :address, :facebook, :twitter, :google, :instagram, :pinterest, :ship_details]
temp[name] = row[row_headers[name.to_s]] ||= ""
end
business = target_model.new(temp)
business.save
end
從代碼檢查站點收到的替代解決方案:
CSV.parse(csv_file, {headers: true, header_converters: :symbol}) do |row|
business_type_id = case row[:business_type_id]
when 'Online' then 1
when 'Local' then 2
else 3
end
target_model.new( {business_type_id: business_type_id} + extract_required_fields(row) + extract_optionals_fiels(row) )
.save()
end
def extract_required_fields(row)
[:user_id, :name, :country_id, :free_shipping, :category_ids, :style_ids, :shipping_country_ids]
.reduce({}) do |carry, item|
carry[item] = row[item]
end
end
def extract_optionals_fiels(row)
[:homepage, :telephone, :email, :address, :facebook, :twitter, :google, :instagram, :pinterest, :ship_details]
.reduce({}) do |carry, item|
carry[item] = row[item] ||= ''
end
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.