在Rails中批量导入CSV?

我正在使用FasterCSV将上传的文件导入到模型中,并且它适用于小文件。 但是,当我尝试导入大型数据集(21,000行)时,需要很长时间才能在实时服务器上获得浏览器超时。

这是我目前的工作代码:

logcount=0 Attendee.transaction do FCSV.new(file, :headers => true).each do |row| row[1] = Date.strptime(row[1], '%m/%d/%Y') record = @event.attendees.new(:union_id => row[0], :dob => row[1], :gender => row[2]) if record.save logcount += 1 end end end 

我喜欢使用后台进程,但用户需要先查看导入的行数,然后才能进入系统的下一步。

所以,我认为我应该使用动作分块 ,只读取少量行,设置一个计数器,然后用某种进程更新视图,然后使用前一个计数器作为起点再次运行该方法。

我似乎无法看到如何让FasterCSV只读取一定数量的行,并设置起点的偏移量。

有谁知道如何做到这一点? 或者有更好的方法来处理这个问题吗?

尝试AR导入

老答案

您是否尝试过使用AR Extensions进行批量导入? 当您向数据库插入1000行时,您可以获得令人印象深刻的性能改进。 访问他们的网站了解更多详情。

我宁愿创建一个准备好的查询,从文件加载一行并执行准备好的查询。 没有任何使用模型,应该更快。

如果您有数据库,为什么不通过Rake任务导入它? 您的用户是否会导入这样的大型数据库?

如果您的用户将要导入此类大型数据库,则任务将无法执行。

FCSV.new可以采用IO.open可以选择的任何选项。 您可以使用它来寻找特定字节。 不幸的是,FCSV不容易停止或访问底层IO对象,以找出你停在哪里。 在文件中间恢复也会使标题行的使用变得复杂。

实际上,我认为最佳解决方案是将您的CSV导入外包给drb,它会以控制器操作可以接收的方式定期报告其进度。 然后经常在客户端上运行一些AJAX来调用该控制器操作。

我过去在BackgroundDRb上取得了成功。 它的安装和使用对我来说有点太详细了。 还有其他一些插件和gem可用google搜索。

DRb警告大多数DRb解决方案都需要在服务器上运行其他守护进程。 一些webhosts在更基本的计划上禁止这个。 检查你的服务条款