2016-06-16 2 views
0

Ich bekomme die falsche Codierung von der jeremyevans-postgres-pr Adapter, die eine der Sequel empfiehlt.Wie verhindere ich, dass Sequels postgres-pr-Adapter Daten mit der falschen Kodierung zurückgibt?

Gibt es etwas, das ich falsch mache?

Beispielcode:

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 

Ausgang:

String Paracelsium "Paracelsium" ASCII-8BIT 
String £0.00 "\xC2\xA30.00" ASCII-8BIT 

Unnötig zu sagen, bekomme ich die gleichen Ergebnisse von Sequel selbst. Und meine Datenbank ist nicht nach ASCII kodiert, sondern nach UTF8.

  • Gerade jetzt muß es PostgreSQL sprechen sowohl mit Ruby und JRuby, und es macht Sinn, zu versuchen, die gleiche Werkzeugkette jeweils zu verwenden, so ist dies der offensichtliche Adapter zu verwenden. Aber.

  • Die original adaptor, dass Jeremy gegabelt sich gleich verhält.

  • Ich kann dieses Problem beheben die Codierung auf der ganzen Linie durch zwingen, aber das wird ein königlicher Schmerz in allen meinen Code zu tun ...


einige zusätzliche Antworten, die ich sollte wohl haben zur Verfügung gestellt (danke):

  • Versionen -> Centos 7; Ruby 2.3.1 & JRuby 9.1.1.0; gem Version 0.6.6
  • OS Gebietsschema -> "LANG = de_DE.UTF-8"
  • Ruby defaults -> Encoding.default_internal = nil; default_external = Kodierung :: UTF-8
+1

Welche Ruby-Version verwenden Sie? Welches OS und welche Gebietsschemaeinstellung hat es? Was ist die Ausgabe von Encoding.default_internal und Encoding.default_external? Was passiert, wenn Sie das Skript wie folgt ausführen: "ruby -E UTF-8 meinskript.rb" –

+0

Gute Fragen, danke. Das allgemeine Zeug habe ich oben beantwortet. Zu Ihrer letzten Frage: keine Änderung ... –

+0

Nur um sicher zu sein: Können Sie die Ausgabe von "psql -l" überprüfen? Sollte die Verschlüsselung Ihrer DBs anzeigen. –

Antwort

1

postgres-pr unterstützt keine Kodierungen. Es ist nicht etwas, das ich mir selbst hinzufügen möchte, aber ich wäre bereit, Patches in Betracht zu ziehen.

Sie können das Sequel :: Model-Plugin force_encoding verwenden, um die Codierung zu korrigieren, zumindest für Orte, an denen Sie Modelle verwenden.

+0

Fair genug. Irgendeine Idee, warum es Standard zu ASCII ist? –

1

Ich habe versucht, Ihr Code-Beispiel auf einer meiner DBs und alles funktioniert wie erwartet. Vielleicht etwas Besonderes für Ihr Setup? Sie können Client-Kodierung überprüfen mit

p c.query("SHOW client_encoding;").rows.first 

Und sollte es einrichten können, mit:

p c.query("SET CLIENT_ENCODING TO 'UTF-8';") 

Nach einiger Feedback von Andy Jones und der Kommentar von Jeremy ich in den Quellcode ein bisschen mehr sah. Bearbeiten der Frage, damit ich bessere Formatierungsoptionen als als Kommentar habe.

Der Fahrer liest US-ASCII aus dem Strom wie folgt:

buffer.copy_from_stream(stream, length-4) 

source code

Dies wiederum ruft Buffer#write, die die Daten in seiner eigenen Einsätze @content:

@content[@position, sz] = str 

source code

Jetzt @content ein String mit einer bestimmten Größe ist, gefüllt mit # Zeichen und es wird wie folgt erstellt:

def self.of_size(size) 
    raise ArgumentError if size < 0 
    new('#' * size 
end 

Dieses @content ein Setup Ihr ​​System ist UTF-8 String, da macht Verwenden Sie UTF-8. Das Zusammenführen eines US-ASCII Zeichens in eine UTF führt zu einer Zeichenfolge __UTF-8. Ab diesem Zeitpunkt findet keine Konvertierung mehr statt und sollte in dieser Codierung verbleiben. Der Spalteninhalt gelesen, um die Buffer.read Methode verwendet, die tut dies:

@content[@position, n] 

source code

diese lange Erklärung nur zu sagen: Ich verstehe nicht, warum Sie sehen US-ASCII Ausgang :-(

SOFERN. Ihr System nicht eingerichtet ist UTF-8 auf eine seltsame Art und Weise zu verwenden

Standardkodierung war US-ASCII mit Ruby 1.9 und geändert in UTF-8 mit Ruby 2.2 (oder früher, nicht sicher?).

Haben Sie einen am Anfang der Datei

# encoding: 

Stil Kommentar haben?

Was ist, wenn Sie

tun geschieht
puts String.new.encoding 

Was ist der Wert von

ist
puts __ENCODING__ 

Was ist der Wert von

ist
puts RUBY_VERSION 

Bitte überprüfen Sie in der gleichen Datei, die Sie das ausführen db-Testskript

+0

Leider sind Sie nur halb rechts. Ich kann die Codierung tatsächlich so einstellen, und wenn ich die Codierung wie vorgeschlagen zeige, bestätigt das, dass sich die Codierung geändert hat. .... * und dann gibt es weiterhin die Daten mit der ASCII-Kodierung, unverändert * ... –

+0

Schade. "Es funktioniert auf meiner Maschine" (tm). Mit Ruby 2.2.x. –

+0

Sie müssen zugeben, es ist ziemlich beeindruckend, dass es auf Ihrem Computer funktioniert, da der Betreuer selbst diese Frage beantwortet, dass Codierungen werden nicht unterstützt;) –

0

Der Schlüssel zum Verständnis, was hier passiert, sind die verschiedenen Einstellungen für die Codierung in Ruby. Es gibt:

  • das Locale-Encoding-Set mit dem magischen Kommentar oder der Befehlszeilenoption -k.

  • die externe Standardkodierung mit Encoding.default_external oder --external-Codierung oder -E gesetzt

  • Der Standard interne Codierung, eingestellt mit Encoding.default_internal oder --internal-Codierung (oder -E nach einem Doppelpunkt)

  • Ruby wird standardmäßig eine Zeichenfolge für die interne oder externe Codierung basierend auf einigen ziemlich unordentlichen Regeln festlegen. Einzelheiten finden Sie unter the documentation. Aber der wichtige Teil hier ist, dass, wenn eine Zeichenfolge aus Binärdaten erstellt wird, es scheint, dass die interne nicht die externe Codierung ist, die verwendet wird.

    Meine interne Codierung ist Null, so dass das nicht geschah. (ASCII-8BIT ist die Kodierung, die Sie erhalten, wenn Ruby nicht weiß, was die Kodierung ist - es bedeutet im Grunde bedeutet "das sind nur Daten für mich; viel Glück beim Lesen".)

    Wenn ich --internal-encoding UTF-8 übergebe Befehlszeile, das Problem verschwindet. In gewisser Hinsicht hat das also nichts mit Jeremys Juwel zu tun.

    Wenn ich -E UTF-8 auf die Befehlszeile legte, legte das die Standardeinstellung externe Codierung. Was hat in diesem Fall nichts gemacht.

    EDIT: Es ist in diesem Fall gearbeitet, aber unter bestimmten (alle?) Umstände Ruby Transcodierungs die Zeichenfolge an die interne Codierung, anstatt nur die Codierung Wert wie in force_encoding Einstellung. Dieses Zeug ist hart.

    Verwandte Themen