[英]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.