我目前正试图导入超过40 CSV的从sqlite3导出到oracle db,但我似乎有问题,同时导入一些的CSV文件,到相应的表中。
包含:
的代码行
class_name.create!(row.to_hash)
在某些类上产生错误,因为当
.create!()
方法被称为
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
手头的问题是,我的CSV导入功能是在seeds.rb
,所以每当我运行bundle exec rake db:seed
CSV的导入。
当class_name.create!(row.to_hash)
在seeds.rb
的函数内被触发时,我该如何避免回调被触发?
在我的customer.rb
我有回调,如:
after_create :add_default_user
或after_create :add_build_config
我想在seeds.rb
中操作我的函数,以便在函数尝试导入像customers.csv
这样的CSV文件(逻辑上调用Customer.create!(row.to_hash)
)时跳过回调。
有较低级别的方法不会运行回调。例如,可以调用insert!
而不是create!
。您可以调用delete
而不是destroy
。
旁注:使用insert_all!
一次批量插入多行。您的导入将更快,而且它不使用验证。不过我还是推荐更灵活的active-import
。
但是,跳过回调可能会导致问题,如果它们是数据完整性所必需的。如果您用delete
代替destroy
关联的数据可能不会被删除,或者您可能会因为引用完整性而得到错误。确保在外键上添加on delete
操作以避免这种情况。然后数据库自己会处理它。
考虑db:seeds是否做得太多了。如果导入这个CSV妨碍了数据库的播种,那么考虑是否应该将它作为一个单独的rake任务。
考虑是否可以将回调重写为幂等的,即能够多次运行。例如,after_create :add_default_user
应该识别已经存在一个默认用户,而不会尝试重新添加它。
最后,考虑每次创建模型时运行的回调是否是执行此工作的正确位置。