0

MySQL の高速インポート LOAD DATA INFILE を使用するために、Ruby のデフォルトの CSV ライブラリで CSV を作成したいと考えています。

現在、フィールドに nil を入力すると、 のように記述されますが...;;...、代わりに...;\N;...(NULL の場合は大文字の N、\n 改行と混同しないように) にしたいと考えています。

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

現在、10 進数フィールドが NULL ではなく 0.00 としてデータベースにロードされています。

後で NULL に設定することもできますが、何百万もの行といくつかの列が影響を受けるため、MySQL が期待するように CSV を記述することを強く好みます。

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

4

2 に答える 2

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ファイルを作成する方法を知っています。

于 2012-08-29T12:05:15.960 に答える
0

nilto_sメソッドを次のようにオーバーライドしてみてください。

class << nil
  def to_s
    "my nil placeholder text"
  end
end

使用するすべてのコードto_sは、値 nil に対してこの実装を使用します。

于 2012-08-29T10:35:02.720 に答える