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
orafter_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.