1
votes

When I run this piece of code with a task, it works

task :importGss => :environment do
    Gss.delete_all
    file = Rails.root + "app/assets/CSVs/gss.csv"
    csv_text = File.read(file)
    puts csv_text.size
    csv = CSV.parse(csv_text, :col_sep => ';', :headers => true)
    csv.each do |row|
    Gss.create!(row.to_hash)
end  

When I run it with a MVC, I have the following message :

ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked:

I have put the above code in a function in the Gss model. The import is launched from the browser with a GET that is routed to the controller that calls the model import function When the import is finished, the complete list of record should then be returned to the view. the csv file has 4k rows. The process of importing takes time and it seems that after precisely 60 seconds the GET is resend. Can someone explain me how to avoid this resending that crashes the import ?

1

1 Answers

4
votes

Wrapping it in a transaction will make sure all the queries will be run together, rather than 1 at a time. This will drastically decrease the time taken to execute the import for that many rows.

task :importGss => :environment do
    Gss.delete_all
    file = Rails.root + "app/assets/CSVs/gss.csv"
    csv_text = File.read(file)
    puts csv_text.size
    csv = CSV.parse(csv_text, :col_sep => ';', :headers => true)

    ActiveRecord::Base.transaction do
      csv.each do |row|
        Gss.create!(row.to_hash)
      end  
    end
end  

Read more on transactions here: http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html