簡體   English   中英

嘗試使用Ruby 1.8 / FasterCSV解析帶有umlaut等的CSV文件時出現問題

[英]Problems trying to parse CSV file with umlaut's etc in it using Ruby 1.8 / FasterCSV

我有一個CSV文件,其中包含以下內容:

...,"Städtische Galerie im Lenbachhaus",...

我正在使用帶有FasterCSV gem的Ruby 1.8,如下所示:

FasterCSV.foreach(file, :encoding => 'u', :headers => :first_row) do |r|
    as = ImportObject.create!(r.to_hash)
end

對於大多數行,它的工作正常,但是對於這些行,帶有特殊字符的字段將被截斷,因此我們將“ St”保存在數據庫中。

我已經把$ KCODE =“ u”加上/不帶編碼選項了,都沒有用。

該數據庫是MySQL。

編輯:

我嘗試將代碼推送到Heroku(Postgres),現在遇到一個新錯誤:

2011-02-19T17:19:01-08:00應用程序[web.1]:ActiveRecord :: StatementInvalid(PG錯誤:錯誤:用於編碼“ UTF8”的字節序列無效:0xe46474

2011-02-19T17:19:01-08:00 app [web.1]:提示:如果字節序列與服務器期望的編碼不匹配,則該錯誤也可能發生,該編碼由“ client_encoding”控制。

2011-02-19T17:19:01-08:00 app [web.1] ::插入“ import_objects”(...“ title”,...)值(...,'St?dtische Galerie im Lenbachhaus',...)返回“ id”):

:(

如您所料,該問題很可能是文件編碼問題。 最可能的情況是您的文件實際上並未使用UTF-8編碼,因此您的應用程序的其余部分無法識別外部編碼。 在編碼中使用的字節之一是ASCII引號或逗號也是有可能的,但我相信這不太可能,這會混淆FasterCSV解析數據。

首先,使用CSV文件中的“問題行”制作一個測試文件。 接下來,讀取文件中的數據:

text_in = File.read('data.csv')

現在,您必須對其進行轉換。 問題是,您真的不知道它是什么。 您將不得不嘗試一些其他的事情。 我最好的猜測是文本是Latin-1編碼的。

require 'iconv'
text_out = Iconv.conv("UTF8", "LATIN1", text_in)

現在嘗試導入此數據。 或者,您可以寫入磁盤並打開它,然后查看其編碼是否正確。

但老實說,您可以在Ruby之外更輕松地執行此操作。

$ iconv -t UTF8 -f LATIN1 < data.csv > data_conv.csv

進一步閱讀:

問題不是FasterCSV,因為在我的測試中,FasterCSV讀取此數據沒有問題。 例如:

>> FasterCSV.parse("a,Städtische Galerie im Lenbachhaus,b,ä", :headers => [:a,:b,:c,:d]) do |r|
|    r = r.to_hash
|    p r
|    puts r[:d]
|  end  
{:c=>"b", :a=>"a", :d=>"\303\244", :b=>"Städtische Galerie im Lenbachhaus"}
ä

請注意,Ruby 1.8不能正確處理unicode字符,但原則上這會影響String#length類的東西。 例如,Ruby將返回此字符串的長度,而不是33,而不是33。但這不會影響您,直到您對字符串進行了某些操作(例如對其進行驗證)。

>> "Städtische Galerie im Lenbachhaus".length
=> 34
>> "Stadtische Galerie im Lenbachhaus".length
=> 33

所以我的猜測是關於ImportObject或如何配置數據庫連接。


這些測試中使用的Ruby版本:

>> RUBY_DESCRIPTION 
=> "ruby 1.8.7 (2010-04-19 patchlevel 253) [i686-darwin10.4.0], MBARI 0x6770, Ruby Enterprise Edition 2010.02"

您沒有說要使用哪種數據庫類型,但是很可能數據庫未配置為UTF-8,而是期望使用ASCII。 拋出非ASCII字符可能會導致字符串被截斷,字符丟失或被占位符替換,這取決於數據庫以及您要與之通信的gem或ORM。 構建數據庫時,請確保已針對UTF-8配置了該數據庫,或者確保我輸入的文本已編碼,以便可以進行往返而不會損壞或丟失。 我學到的教訓與您一樣,很艱難。

檢查數據庫的日志,和/或檢查您的代碼,以查看是否可以為數據庫插入啟用日志記錄以及錯誤和警告消息。

在許多數據庫中禁用警告和錯誤很容易,但是在開發過程中,您不想這樣做。 這些消息很重要,可以預示即將出現的大問題。 忽略它們並將代碼推入生產環境可能是不眠之夜的真正秘訣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM