我正在使用主动管理员并将记录从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
答案 0 :(得分:0)
我将专注于将CSV行转换为对象。在除非身体中只有很多重复。所有这些行都应该被提及一次,然后在循环中处理而不是像这样硬编码。 E.g。
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