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.
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.
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.
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?
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
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.