使用Ruby和Sinatra,如何上传csv文件并将每行插入postgres数据库?

时间:2014-01-27 03:29:33

标签: ruby postgresql csv sinatra

我正在使用Sequel,Sinatra,Postgres和ruby。我有一个表单上传一个工作正常的csv文件,问题是解析并将csv文件中的字段插入postgres数据库。 csv文件的结构如下:

first,last,designation,email,phone,company,remarks,owner,date
John,McAndrew,CEO,debra.wagman@callcreditgroup.com,44 113 388 4300,Callcredit Information Group,none,tim@xxxx.jp,now()

postgres数据库具有相同的字段。

我想保留标题,然后遍历记录(可能有100个)并插入数据库。我首先尝试只有一个字段,然后需要插入所有字段。我到目前为止的红宝石代码是:

 require 'csv'
    post '/upload' do
      file_data = params[:myfile][:tempfile].read
      #file_data = params[:file].read
      csv_rows  = CSV.parse(file_data, headers: true)
      owner = 'tim@xxxx.jp'
      csv_rows.map do |row| 
       {firstname => row[:first]}
          DB[:prospects].insert( :first =>  firstname, :owner => owner )
      end
     end

这不起作用我明白了:PG :: UndefinedColumn:错误:列“firstname”不存在。

然后我尝试了:

 require 'csv'
    post '/upload' do
      file_data = params[:myfile][:tempfile].read
      #file_data = params[:file].read
      csv_rows  = CSV.parse(file_data, headers: true)
      owner = 'tim@xxxx.jp'
      csv_rows.each do |row| 

       DB[:prospects].insert( :first =>  row[:first], :owner => owner )

          end
      end

它不会返回错误但它只插入变量所有者,它完全忽略行[:first]或找不到它。

什么是正确的方法家伙?谢谢!

这有效(在SoulRebel的帮助下):

post '/upload' do
  file_data = params[:myfile][:tempfile].read
  #file_data = params[:file].read
  csv_rows  = CSV.parse(file_data, headers: true)
  owner = 'tim@platformone.jp'
  csv_rows.each do |row| 

   DB[:prospects].insert( :first =>  row[:first], :owner => owner )

      end
end

这也是有效的,经过反复试验后我想通了:

post '/uploading' do
  file_data = params[:myfile][:tempfile].read
  csv_rows  = CSV.parse(file_data, headers: true, header_converters: :symbol)
  owner = 'tim@xxxx.jp'
  remarks = 'none yet'
  csv_rows.each do |row| 
      DB[:prospects].insert( :first =>  row[:first], :last => row[:last], :designation => row[:designation], :email => row[:email], :phone => row[:phone], :company => row[:company], :industry => row[:industry], :city => row[:city], :country => row[:country], :status => row[:status],  :remarks => remarks, :owner => owner )
    end
  return "File successfully uploaded"
end

请注意添加“header_converters :: symbol”

一如既往,感谢SO社区。

1 个答案:

答案 0 :(得分:2)

试试这个:

CSV.foreach($csv_fname, :headers => true) do |csv_obj|
    puts csv_obj['first'] #just to verify that parsing is working well
    DB[:prospects].insert( :first =>  cvs_obj['first'], :owner => csv_obj['owner'] )

end