1

我正在将 csv 数据导入到 Rails 应用程序中的 mysql 中。我已经使用CSV.parse在 csv 文件中逐行读取并导入数据库。这种方法效果很好。


但是,当我部署到 Heroku 服务器时,每个请求的超时时间为 30 秒。如果导入 csv 文件超过 30 秒。Heroku 服务器出现错误:请求超时 - H12。有人帮我找出导入大型 csv 文件的最佳方法吗?现在,我只导入包含 70 个用户的小型 csv。我想导入包含 500 - 1000 个用户的大型 csv。这是代码:

导入控制器:

CSV.foreach(params[:file].path, :headers => true) do |row|
  i = i + 1

  if i == 1
    @company = Company.find_or_create_by!(name: row[0])       
  end

  @users = User.find_by(email: row[1])

  if @users
    if @company.id == @users.employee.company_id
      render :status=> 401, :json => {:message=> "Error"}
      return
    else
      render :status=> 401, :json => {:message=> "Error"}
      return
    end
  else
    # User
    # # Generate password
    password = row[2]
    user = User.new(email: row[1])
    user.password = password.downcase
    user.normal_password = password.downcase
    user.skip_confirmation!
    user.save!

    obj = {
      'small'   => 'https://' + ENV['AWS_S3_BUCKET'] + '.s3.amazonaws.com/images/' + 'default-profile-pic_30x30.png',
      'medium'  => 'https://' + ENV['AWS_S3_BUCKET'] + '.s3.amazonaws.com/images/' + 'default-profile-pic_40x40.png'
    }

    employee = Employee.new(user_id: user.id)
    employee.update_attributes(name: row[3], job_title: row[5], gender: row[9], job_location: row[10], group_name: row[11], is_admin: to_bool(row[13]), 
                is_manager: to_bool(row[14]), is_reviewee: to_bool(row[6]), admin_target: row[7], admin_view_target: row[12], department: row[8], 
                company_id: @company.id, avatar: obj.to_json)
    employee.save!

  end
end

我尝试使用 gems 'activerecord-import' 或 'fastercsv' 但 'activerecord-import' 不起作用,'fastercsv' 不适用于 ruby​​ 2.0 和 rails 4.0

4

3 回答 3

2

在控制器中执行此操作对我来说似乎有点多,尤其是因为它是阻塞的。您是否考虑过将其投入后台工作?

如果我是你,我会:

  1. 上传文件
  2. 在后台将其解析为 rake 任务

另外,看看:https ://github.com/tilo/smarter_csv

于 2013-10-21T03:37:16.440 回答
0

似乎这些行

if i == 1
  @company = Company.find_or_create_by!(name: row[0])       
end

@users = User.find_by(email: row[1])

在 30 秒的时间范围内需要大量的计算周期。

如果我们无法对上面的代码进行一些优化,我建议使用resquedelay_job将您的例程转换为 Heroku 后台进程,或者将例程拆分为n 个请求。

希望这可以帮助。

于 2013-10-21T03:33:46.967 回答
0

delayed_job使用、sidekiq、等产品在后台处理您的 CSV resque。如果它适合您的用例,您甚至可以使用guardor来执行此操作cron

于 2013-10-21T03:53:02.047 回答