【问题标题】:Rails importing CSV fails due to mal-formation由于格式错误,Rails 导入 CSV 失败
【发布时间】:2011-12-28 20:52:55
【问题描述】:

当我尝试使用以下代码导入文件时收到CSV:MalFormedCSVError

  def import_csv(filename, model)
    CSV.foreach(filename, :headers => true) do |row|
      item = {}
      row.to_hash.each_pair do |k,v|
          item.merge!({k.downcase => v})
      end
        model.create!(item)
    end
  end

csv 文件非常大,有没有办法只记录格式错误的行并 CONTINUE EXECUTION 与 csv 文件的其余部分一起记录?

【问题讨论】:

    标签: ruby-on-rails ruby csv ruby-on-rails-3.1


    【解决方案1】:

    使用File 手动遍历文件中的每一行的一个问题是CSV 文件可以包含带有\n(换行符)的字段。 File 会用它来表示换行符,你最终会尝试解析部分行。

    这是另一种可能适合您的方法:

    @csv = CSV.new('path/to/file.csv')
    
    loop do
      begin
        row = @csv.shift
        break unless row
        # do stuff
      rescue CSV::MalformedCSVError => error
        # handle the error
        next
      end
    end
    

    我看到这种方法的主要缺点是您在处理错误时无法访问 CSV 行字符串,只能访问 CSV::MalformedCSVError 本身。

    【讨论】:

    • 这会将整个文件加载到内存中,对吗?任何与 foreach 具有相同行为的替代方案?
    • @buncis 已经有一段时间了,但据我回忆,shift 方法是 CSV 库在后台使用的方法,用于从 CSV 文件中读取 both 的各个行 i> 将整个文件加载到内存的方法以及 将整个文件读入内存的方法,所以这也应该避免加载整个文件除非您在循环中执行的任何操作中保存对 row 变量的引用,否则将其保存到内存中。
    • 是的,这里已确认ruby-doc.org/stdlib-2.6.1/libdoc/csv/rdoc/…btw why I cannot tag people?
    【解决方案2】:

    您可以尝试自己处理读取的文件,并让 CSV 一次处理一行。像这样的:

    File.foreach(filename) do |line|
      begin
        CSV.parse(line) do |row|
          # Do something with row...
        end
      rescue CSV::MalformedCSVError => e
        # complain about line
      end
    end
    

    当然,您必须自己处理标题行。此外,如果您在 CSV 中嵌入了换行符,这将不起作用。

    【讨论】:

    • 我不能权威地发言,但我的理解是,如果字段包含\n,这种方法可能会适得其反,因为File 会将其视为新行的开始,而内置的 CSV 库知道如何适当地处理它。也许其他人可以谈论这个......
    • @toasterlovin 是的,这可能是个问题。但是,在这种情况下,您不能让CSV 完成这项工作,因为有问题的 CSV 文件有一些格式错误的记录,而且似乎半损坏的 CSV 文件使CSV.foreach 无法正常工作。
    • 今晚我在玩这个,替代方法即将到来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2020-02-18
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多