Ruby CSV:如何将nil字段写为\ N.

时间:2012-08-29 09:07:48

标签: mysql ruby csv

我想用ruby的默认CSV库编写一个CSV,以便使用MySQL的快速导入LOAD DATA INFILE。

目前,当我为某个字段输入nil时,它被写为...;;...,而我希望它为...;\N;...(大写N表示NULL,不要与\ n换行符混淆)。

CSV.open(product_updates_file_name, "wb", {col_sep: ";", headers: false, force_quotes: false}) do |product_csv|
    product_csv << ["foo", nil, "bar"]
end

它当前导致十进制字段在数据库中加载为0.00而不是NULL。

我知道,之后我可以将它设置为NULL,但是有数百万行和几列受到影响,所以我强烈建议按照MySQL的预期编写CSV:

http://dev.mysql.com/doc/refman/5.1/en/load-data.html

2 个答案:

答案 0 :(得分:0)

尝试覆盖nil的{​​{1}}方法,如下所示:

to_s

使用class << nil def to_s "my nil placeholder text" end end 的所有代码都将使用此实现作为值nil。

答案 1 :(得分:0)

您可以修改CSV方法:

require 'csv'
class Array
  alias :old_to_csv :to_csv
  #Extend to_csv for usage like ["foo", nil, "bar"].to_csv( :col_sep => ";")
  def to_csv(options)
    self.map{|s| s.nil? ? '\N' : s }.old_to_csv 
  end
end  

class CSV
  alias :old_push :<<
  def <<(data)
    case data
      when Array
        old_push data.map{|s| s.nil? ? '\N' : s }
      else
        old_push data
      end
  end
end

#Testcode:
puts ["foo", nil, "bar"].to_csv( :col_sep => ";")   #--> [["foo", "\\N", "bar"]]
CSV.open('test.csv', "wb", 
      {col_sep: ";", headers: false, force_quotes: false }
  ) do |product_csv|     
    product_csv << ["foo", nil, "bar"] 
end 
#-> Creates test.csv with 'foo;\N;bar'

仅在插入数组时才有效。如果插入其他内容,则必须修改逻辑。


注: 我的第一个想法是使用转换器。但它仅用于解析csv,而不是用于编写。

CSV::Converters[:nil_N] = lambda{|s| 
  s.nil? ? '\N' : s
}
p CSV.parse('foo;;bar', :col_sep => ";",  :converters => :nil_N)
#-> [["foo", "\\N", "bar"]]

也许其他人知道使用转换器构建csv文件的方法。