2013-10-21 57 views
1

我正在rails应用程序中导入csv数据到mysql中。我已经使用CSV.parse在csv文件中逐行读取并导入到数据库中。这种方式效果很好。如何在rails应用程序中将大型csv文件导入到mysql中?


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

进口控制器:

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 

我已经尝试使用宝石的ActiveRecord进口“或“fastercsv”,但“ActiveRecord的导入”不行,“fastercsv”不工作红宝石2.0和4.0轨道

回答

0

看来,这些线路

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

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

需要大量的计算周期在30秒时间表。

我会建议使用resquedelayed_job的到你的日常到Heroku的后台程序进行转换,或常规分成ñ请求,如果我们不能有所优化上面的代码。

希望这会有所帮助。

+0

谢谢,我会尽力的。我无法优化上面的代码。项目中的逻辑非常复杂。但是,您可以为我解释“将例程转换为Heroku后台进程,或将例程分成n个请求”。 – Nin

+0

不好意思,说Heroku后台进程时,我介绍了诸如resque和delayed_job之类的宝石。 –

+0

至于'将例程分成n个请求',我的意思是读取并保存控制器中的一个(或30秒内的任何数量的适合的用户),而不是一次解析它们。但是,从您的其他信息,处理它们作为后台进程似乎更容易实现。 –

2

在控制器中做这件事对我来说似乎有点多,特别是因为它阻塞了。你有没有想过把它投入后台工作?

如果我是你,我会:

  1. 上传文件
  2. 解析它在后台rake任务

而且,看看:https://github.com/tilo/smarter_csv

+0

我仍然尝试rake任务命令,但客户端要从UI导入:-s。 – Nin

+0

客户端?什么UI? – AdamT

+0

对不起,客户想从UI控制器导入用户,他们不知道后台作业。 – Nin

0

使用诸如delayed_job,sidekiq,resque之类的产品在后台处理您的CSV。如果它适合你的用例,你甚至可以使用guardcron来做到这一点。

+0

我可以从导入控制器运行耙子任务后台作业,对不对? – Nin

+0

'Rake :: Task ['task_name']。invoke(args)'。但我不推荐这个。应该从控制器外部调用rake任务 - “cron”或“guard”。你当然可以做'系统(“耙......”)或反引号或'%x []' – Litmus

相关问题