簡體   English   中英

在Rails的CSV上傳中進行批處理和錯誤處理

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM