[英]How do I stop Sequel's postgres-pr adaptor from returning data in the wrong encoding?
我從jeremyevans-postgres-pr適配器得到了錯誤的編碼,這是Sequel建議的適配器之一。
我做錯什么了嗎?
示例代碼:
require 'postgres-pr/connection'
c = PostgresPR::Connection.new('blah', 'blah', 'blah')
row = c.query("select name, cost from remedium.prescription").rows.last
row.each do |f|
#f.force_encoding(Encoding::UTF_8) #-- uncomment this to 'fix' everything ;/
enc = f.kind_of?(String) ? f.encoding : ''
puts [f.class, f, f.inspect, enc].join(' ')
end
輸出:
String Paracelsium "Paracelsium" ASCII-8BIT
String £0.00 "\xC2\xA30.00" ASCII-8BIT
不用說,我從Sequel本身獲得了相同的結果。 而且我的數據庫不是編碼為ASCII,而是UTF8。
現在,我需要同時使用Ruby和JRuby與PostgreSQL進行對話,並且在每種情況下嘗試使用相同的工具鏈是很有意義的,因此這顯然是可以使用的適配器。 但。
Jeremy分叉的原始適配器的行為相同。
我可以通過強制全面編碼來解決此問題,但這對我所有代碼來說都是一個皇家痛苦……
我可能應該提供一些其他答案(謝謝):
postgres-pr
不支持編碼。 我不打算加我自己,但我願意考慮補丁。
至少在使用模型的地方,可以使用force_encoding
Sequel :: Model插件來修復編碼。
我在我的一個數據庫上嘗試了您的代碼示例,並且一切正常。 可能對您的設置有些特殊嗎? 您可以使用
p c.query("SHOW client_encoding;").rows.first
並且應該能夠使用以下命令進行設置:
p c.query("SET CLIENT_ENCODING TO 'UTF-8';")
經過安迪·瓊斯的一些反饋和傑里米的評論后,我對源代碼進行了更多研究。 編輯問題,以便我有比注釋更好的格式選項。
驅動程序從流中讀取US-ASCII ,如下所示:
buffer.copy_from_stream(stream, length-4)
依次調用Buffer#write
,將數據插入到自己的@content
:
@content[@position, sz] = str
現在@content是一個特定大小的字符串,用#號填充,它的創建方式如下:
def self.of_size(size)
raise ArgumentError if size < 0
new('#' * size
end
給定您的系統設置為使用UTF-8,這會使@content
成為UTF-8字符串。 將US-ASCII字符串合並為UTF將產生__UTF-8字符串。 從那里開始,不會進行任何轉換,因此應保持該編碼狀態。 使用執行此操作的Buffer.read
方法讀取列內容:
@content[@position, n]
這個冗長的解釋只是說:我不明白為什么您會看到US-ASCII輸出:-(
除非:您的系統未設置為以某種奇怪的方式使用UTF-8。
Ruby 1.9的默認編碼為US-ASCII ,而Ruby 2.2的默認編碼為UTF-8 (或更早版本,不確定嗎?)。
你有沒有
# encoding:
在文件開頭添加樣式注釋?
如果您這樣做會怎樣?
puts String.new.encoding
有什么價值
puts __ENCODING__
有什么價值
puts RUBY_VERSION
請檢入與運行db測試腳本相同的文件。
了解這里發生的事情的關鍵是在ruby中編碼的多種設置。 有:
使用魔術注釋或-k命令行開關設置的語言環境編碼。
默認的外部編碼,使用Encoding.default_external
或--external-encoding或-E設置
默認的內部編碼,設置為Encoding.default_internal
或--internal-encoding(或冒號后面的-E)
Ruby默認會基於一些相當混亂的規則將字符串設置為內部或外部編碼。 有關詳細信息,請參見文檔 。 但是這里重要的是,當從二進制數據創建字符串時,它看起來是內部的而不是所使用的外部編碼。
我的內部編碼為nil,所以沒有發生。 (ASCII-8BIT是當Ruby不知道編碼是什么時得到的編碼,它的基本意思是“這只是我的數據;祝您讀好運”。)
如果我在命令行上通過--internal-encoding UTF-8
,問題就消失了。 從某種意義上講,這與傑里米的寶石無關。
當我在命令行上放置-E UTF-8
時,將設置默認的外部編碼。 在這種情況下沒有執行任何操作。
編輯:在這種情況下它可以工作,但是在某些(所有?)情況下,Ruby會將字符串轉碼為內部編碼,而不僅僅是像force_encoding
那樣設置編碼值。 這東西很難。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.