Home > Mobile >  How to import CSV into database on Rails whilst skipping callbacks
How to import CSV into database on Rails whilst skipping callbacks

Time:09-16

I am currently trying to import over 40 CSV's exported from sqlite3 into oracle db but I seem to have issues whilst importing some of the CSV's, into the corresponding tables.

The code line with:

class_name.create!(row.to_hash)

produces errors on some classes because the callbacks are also triggered when the

.create!() method is called

def import_csv_into_db
  Dir.foreach(Rails.root.join('db', 'csv_export')) do |filename|
      next if filename == '.' or filename == '..' or filename == 'extract_db_into_csv.sh' or filename =='import_csv.rb'
      filename_renamed = File.basename(filename, File.extname(filename)).chomp('s').titleize.gsub(/\s /, "")
        CSV.foreach(Rails.root.join('db', 'csv_export',filename), headers: true) do |row|
          class_name = Object.const_get(filename_renamed)
          puts class_name
          class_name.create!(row.to_hash)
          puts "Insert on table #{class_name}s complete with:  #{row.to_hash}"
      end
  end
end

The issue at hand is that my CSV import function is in the seeds.rb, so whenver I run bundle exec rake db:seed the CSV's are imported.

How exactly can I avoid the callbacks being triggered when class_name.create!(row.to_hash) is triggered within the function in the seeds.rb ?

In my customer.rb I have callbacks such as:

after_create :add_default_user or after_create :add_build_config

I'd like to manipulate my function within the seeds.rb to skip the callbacks when the function tries importing a CSV file like customers.csv (which would logically call Customer.create!(row.to_hash)).

CodePudding user response:

There are lower level methods which will not run callbacks. For example, instead of create! you can call insert!. Instead of destroy you can call delete.

Side note: use insert_all! to bulk insert multiple rows at once. Your import will be much faster and it does not use validations. Though I would recommend the more flexible active-import instead.


However, skipping callbacks might cause problems if they are necessary for the integrity of the data. If you delete instead of destroy associated data may not be deleted, or you may get errors because of referential integrity. Be sure to add on delete actions on your foreign keys to avoid this. Then the database itself will take care of it.

Consider whether your db:seeds is doing too much. If importing this CSV is a hindrance to seeding the database, consider if it should be a separate rake task instead.

Consider whether your callbacks can be rewritten to be idempotent, that is to be able to run multiple times. For example, after_create :add_default_user should recognize there already is a default user and not try to re-add it.

Finally, consider whether callbacks which are run every time a model is created are the correct place to do this work.

  • Related