Search code examples
rubycsvattributesruby-on-rails-3.2rake

Unknown attribute error while executing import.rake to upload csv file


I have been trying to load data in devices.csv file into devices table in DB. However while running

rake db:devices RAILS_ENV=production

above rake command in command line, I am getting unknown attribute: error.

Below is the result trace.

** Invoke db:devices (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:devices
rake aborted!
unknown attribute:
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:88:in `block in assign_attributes'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `each'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/activerecord-3.2.13/lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/activerecord-3.2.13/lib/active_record/base.rb:498:in `initialize'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/oink-0.10.1/lib/oink/instrumentation/active_record.rb:60:in `initialize'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/activerecord-3.2.13/lib/active_record/persistence.rb:44:in `new'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/activerecord-3.2.13/lib/active_record/persistence.rb:44:in `create'
/opt/EDDIE/lib/tasks/import.rake:6:in `block (3 levels) in <top (required)>'
/usr/local/rvm/rubies/ruby-2.0.0-p648/lib/ruby/2.0.0/csv.rb:1719:in `each'
/usr/local/rvm/rubies/ruby-2.0.0-p648/lib/ruby/2.0.0/csv.rb:1120:in `block in foreach'
/usr/local/rvm/rubies/ruby-2.0.0-p648/lib/ruby/2.0.0/csv.rb:1266:in `open'
/usr/local/rvm/rubies/ruby-2.0.0-p648/lib/ruby/2.0.0/csv.rb:1119:in `foreach'
/opt/EDDIE/lib/tasks/import.rake:5:in `block (2 levels) in <top (required)>'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/task.rb:236:in `call'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/task.rb:236:in `block in execute'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/task.rb:231:in `each'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/task.rb:231:in `execute'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/task.rb:175:in `block in invoke_with_call_chain'
/usr/local/rvm/rubies/ruby-2.0.0-p648/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/task.rb:168:in `invoke_with_call_chain'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/task.rb:161:in `invoke'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:149:in `invoke_task'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:106:in `block (2 levels) in top_level'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:106:in `each'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:106:in `block in top_level'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:115:in `run_with_threads'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:100:in `top_level'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:78:in `block in run'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:165:in `standard_exception_handling'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/lib/rake/application.rb:75:in `run'
/usr/local/rvm/gems/ruby-2.0.0-p648/gems/rake-10.1.1/bin/rake:33:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.0.0-p648/bin/rake:23:in `load'
/usr/local/rvm/gems/ruby-2.0.0-p648/bin/rake:23:in `<main>'
/usr/local/rvm/gems/ruby-2.0.0-p648/bin/ruby_executable_hooks:15:in `eval'
/usr/local/rvm/gems/ruby-2.0.0-p648/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => db:devices

Here is my rake file in lib/tasks folder.

require 'csv'
namespace :db do
  desc "Import devices from csv file"
  task :devices => [:environment] do
      CSV.foreach('devices.csv', :headers => true, :encoding => 'ISO-8859-1:UTF-8') do |row|
      Device.create(row.to_hash)
    end
  end
end

Can anyone plz help how to ignore this error and load the data into DB?


Solution

  • I think there's something in your header that doesn't match with a column name.

    When importing data like that, if you don't want to bother mapping each csv column to Model attributes to guarantee it would work, you can just ignore columns that don't have matching headers.

    Using your example, it could be something like this:

      task :devices => [:environment] do
          CSV.foreach('devices.csv', :headers => true, :encoding => 'ISO-8859-1:UTF-8') do |row|
          params = row.to_hash.with_indifferent_access.select{ |x| Device.attribute_names.index(x)}
          Device.create(params)
        end
      end