Migration von 7.4 auf 8.3 mit unterschiedlichem Encoding

Hallo zusammen

Ich habe eine DB auf PostgreSQL 7.4 mit Encoding SQL_ASCII auf Linux am laufen. Jetzt möchte ich diese DB auf PostgreSQL 8.3 auf einen anderen Host migrieren. Das Encoding soll zukünftig UTF8 sein.

Mit dem Tool pg_dump wird unter der Version 7.4 noch kein Encoding Attribut unterstützt. Nun gut, ich habe pg_dump der 8.3er Version auf dem zweiten Server angewendet und die Daten übers Netz gezogen.

Folgender Aufruf habe ich für die Erstellung des Dump verwendet:

pg_dump -f dump.tar -Ft -h host.xy.org -U user

Importiert habe ich den Dump auf einer DB mit Encoding=UTF8 folgendermassen:

pg_restore -d db -U user dump.tar

Beim Import erhalte ich folgende Fehlermeldungen:

pg_restore: [archiver (db)] Error from TOC entry 1769; 0 934492 TABLE DATA tbl_x
pg_restore: [archiver (db)] COPY failed: ERROR:  invalid byte sequence for encoding "UTF8": 0x96
HINT:  This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
CONTEXT:  COPY tbl_x, line 670
pg_restore: [archiver (db)] Error from TOC entry 1746; 0 934352 TABLE DATA tbl_y
pg_restore: [archiver (db)] COPY failed: ERROR:  invalid byte sequence for encoding "UTF8": 0xfc
HINT:  This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
CONTEXT:  COPY tbl_y, line 187
pg_restore: [archiver (db)] Error from TOC entry 1731; 0 934314 TABLE DATA tbl_z swisstopo
pg_restore: [archiver (db)] COPY failed: ERROR:  invalid byte sequence for encoding "UTF8": 0x92
HINT:  This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
CONTEXT:  COPY tbl_z, line 75

Kann mir jemand erklären weshalb? client_encoding und server_encoding sind beide auf UTF8 konfiguriert.

Vielen Dank im Voraus und Gruss
Ben

Nun, wieso steht dein client_encoding auf UTF8, wenn du doch nicht weißt, ob deine Daten wirklich UTF8 sind?

Wenn die Daten wirklich UTF8 sind - sind sie falsch. PostgreSQL lässt nur gültige Daten in die Datenbank, daher werden deine Eingaben abgelehnt mit dem Hinweis, dass es diese Zeichenkombination in UTF8 nicht gibt.

Hallo

Du meinst dies sind Zeichen welche im UTF8 Zeichensatz nicht unterstützt werden - in SQL_ASCII jedoch schon?

Oder sollte ich beim Einlesen des Dump das client_encoding auf SQL_ASCII setzen?

Hallo nochmals

Ich habs mit folgender Lösung hingekriegt:

Den Dump erstelle ich als Plaintext und nicht als tar. Danach wandle ich das Encoding des Files von SQL_ASCII (ISO8859-1) nach UTF-8 mit «iconv» um:

iconv -f ISO8859-1 -t UTF-8 dump_ascii.sql > dump_utf.sql

Danach den Dump einlesen:

cat dump_utf.sql | psql -U user database > success.log

Gruss
Ben

Du übersiehst da etwas: SQL-ASCII untersucht die Daten nicht sondern nimmt die so wie sie sind als gegeben an. Dabei findet auch keine Umwandlung z. B. von Latin1 in UTF8 statt.

Wenn du deine fehlerhften Daten allerdings als SQL-ASCII in die Datenbank spielst, musst du beim Auslesen das Encoding auch wieder umschalten. Sonst versucht PostgreSQL, die Daten in UTF8 für den Export umzuwandeln - und das schlägt fehl.

Du Hast recht!

Gibt’s denn überhaupt eine Möglichkeit dieses Problem zu lösen? Oder bleibt mir nichts anderes übrig als auf der bestehenden DB die entsprechenden Werte manuell nach UTF-8 zu ändern?

Du hast meine Eingangsfrage noch nicht beantwortet: sind das Daten, die im UTF8 Format vorliegen sollen? Oder sind das binäre Daten, die keinen Zusammenhang mit einer Textrepräsentation haben?

Nein, die DB enhält keine binären Daten. Als Format der bisherigen Datenbank ist SQL_ASCII konfiguriert.

Nein, langsam, ich habe meine Frage wohl undeutlich definiert:

Sind das Texte, die du dort hast?
Und wenn ja, in welchem Encoding sollten diese theoretisch vorliegen?

Ja, es handelt sich um Texte. Theoretisch sollten diese wohl im LATIN1 Format vorliegen.

Ich könnte mir jedoch vorstellen, dass es einige Zeichen gibt, welche falsch eingetragen werden (z.B. durch Benutzer welche über ODBC Daten eingetragen haben).

Wahrscheinlich ist es unvermeidbar die jeweiligen Zeichen manuell zu ersetzen…

Ja, das sieht dann so aus, als ob diese Daten falsch sind.

Du kannst dir jetzt überlegen, ob du weiterhin ohne Encoding fahren willst, dann muß deine neue Datenbank auch SQL_ASCII sein. Oder ob du einmal den Aufwand wagst und alles richtig stellst.

Die Entscheidung kann dir keiner Abnehmen :wink:


P.S.: Wenn die Daten Latin1 waren, sollte dein client_encoding auch wieder Latin1 sein. PostgreSQL rechnet das dann richtig in UTF8 um - abzüglich ev. vorhandener Fehler in den Texten.