2012-08-29 18 views
0

我想用ruby的默認CSV庫編寫一個CSV文件,以便使用MySQL的快速導入LOAD DATA INFILE。Ruby CSV:如何將無字段寫爲 N

目前,當我進入零的領域,它被寫爲...;;...,而不是我想這是...;\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 

它當前導致數據庫中的小數點字段被加載爲0.00而不是NULL。

我知道,我可以將它設置爲NULL算賬,但也有幾百萬行,影響多列的,所以我強烈prefere寫的CSV作爲MySQL的希望我:

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

回答

0

嘗試重寫nilto_s方法,像這樣:

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

使用to_s將使用值爲零這個實現的所有代碼。

+0

它是一個巨大的rails應用程序的一部分,所以我會提供更多的本地解決方案。不過,謝謝。 – Jan

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文件的方法。

+0

我也嘗試使用轉換器,並且無法啓動它。我會嘗試你的其他解決方案,謝謝。 – Jan

相關問題