第1行中缺少或流浪的引用(CSV :: MalformedCSVError)

时间:2015-03-26 21:27:59

标签: ruby-on-rails ruby csv

我在ruby / rails

中导入此CSV文件时遇到问题

我得到的错误信息是:

Missing or stray quote in line 1 (CSV::MalformedCSVError)

但是我不确定发生了什么,因为我的CSV看起来非常好。以下是示例数据:

"lesley_grades","lesley_id","last","first","active","site","cohort","section","sections_title","faculty","completed_term_cred","term","sec_start_date","sec_end_date","grade","stc_cred","active_program","most_recent_program","intent_filed","stc_term_gpa","sta_cum_gpa","start_term","prog_status","last_change_date"
,1234456,John,Doe,TRUE,"Baltimore, MD",0002012,14/FA_ERLIT_6999_U15AA,Directed Independent Study,"Jane Hicks , Jill Saunders",2,14/FA,9/3/14,12/17/14,B-,2,EME.2270.TCBAL.01,EME.2270.TCBAL.01, ,3.3,3.148,12/SU,A,9/2/14
,1234455,John,Doe,TRUE,"Baltimore, MD",0002012,14/FA_ERSPD_6999_U15AG,Directed Independent Study,"Jane Hicks , Jill Saunders",3,14/FA,9/3/14,12/17/14,A-,3,EME.2270.TCBAL.01,EME.2270.TCBAL.01, ,3.3,3.148,12/SU,A,9/2/14

为了给出上下文,有效的csv看起来像这样,lesley_grades作为第一列。假设所有迁移都是预先设置的,则over CSV脚本文件将查找第一列并检查该活动的Active Record对象,然后将其存储为具有完全相同模型名称的db。

lesley_grades   lesley_id   last   first    active  
                 1234556    Doe    John     TRUE    
                 1123445    Doe    John     TRUE

以下是导致我出现问题的代码的一部分

def import!(csv)
 csv_reader = CSV.parse(csv)
 ActiveRecord::Base.transaction do
  csv_reader.each do |row|
    set_record_class_and_columns(row) if header_row?(row)

    if columns_mapping_defined? && record_class_defined? && record_row?(row)
      import_row(row)
    end
  end
  if imports_failed?
    puts 'Aborting importing and rolling back...'
    show_errors
    raise ActiveRecord::Rollback
  end
end

无法通过此行csv_reader = CSV.parse(csv)

之前我把引号放在标题中我得到了这个错误

Unquoted fields do not allow \r or \n (line 1). (CSV::MalformedCSVError)

更新

CSV从命令行开始,如下所示:

rails runner scripts/import_csv.rb < lesley_grades.csv

然后在这里初始化

CSVImporter.new.import!($stdin)

但正如@smathy建议我将方法改为CSV.parse(csv.gsub / \ r /,'')

但是现在def import!块中的gsub方法会产生此错误

in `import!': undefined method `gsub' for #<IO:<STDIN>> (NoMethodError)

不确定如何将CSV设为对象?

为使这项工作有任何建议或重构? 谢谢大家

3 个答案:

答案 0 :(得分:12)

您的CSV数据来自Windows,并且有CRLF(即。&#34; \ r \ n&#34;)行结尾而不是&#34; \ n&#34;,您需要删除&#34; \ r&#34; s在尝试解析它之前:

CSV.parse(csv.gsub /\r/, '')

更新

来自OP的其他信息:

CSV.parse(csv.read.gsub /\r/, '')

答案 1 :(得分:1)

如果未正确设置CSV列分隔字符,您可能还会遇到此问题。

默认情况下,Ruby假定为,。大多数开源软件都是如此,比如OpenOffice。 相反,Microsoft Excel在导出为CSV时使用;

因此,请使用col_sep选项,如下所示:

CSV.parse(csv, col_sep: ';')

答案 2 :(得分:1)

此错误也可能由双引号引起,双引号不在字段的开头,也不会使用两个双引号进行转义。

以下示例中的第三个字段中会出现错误:

"Issue", "posted by Gary", "He said "I'm having issues importing" ","12345"

“我遇到问题”中的双引号将被stray_quote中的常规表达式(/ [^“]”[^“] /捕获,这是用于引发的csv.rb文件中的变量第1863行的MalformedCSVError错误。

要解决这个问题,你需要使用另一个双引号来转义双引号,如下所示:

"He said ""I'm having issues importing"" "

希望这有帮助。