MySQL > PostgreSQL ES WILL EINFACH NICHT KLAPPEN

Hi Leute,

sorry für mein Capslock-Ausrutscher im Titel, aber ich bin fix und fertig. :rolleyes:
Meine MySQL Daten sollen in meine neue PostgreSQL Datenbank eingefügt werden.
Ich habe Windows XP 32bit und das aktuellste PostgreSQL am laufen. Folgendermaßen bin ich bis jetzt vorgegangen:

mysqldump.exe -u root -p --compatible=postgresql --default-character-set=latin1 meinedb > “D:\Data\DUMP.sql”

Danach habe ich die sql Datei manuell mit Wordpad geöffnet und eigentlich alle nichtkonformen Datentypen wie tinyint(1) zu boolean und so weiter umgewandelt. Google hat mir da sehr geholfen. Danach hatte ich einen sauberen Dump. Danach füge ich es mit folgender Zeile in PostgreSQL ein:

psql.exe -h localhost -d testdb -U postgres -encoding=latin1 -f “D:\Data\DUMP.sql”
Jetzt allerdings bekomme ich folgende Fehlermeldung:

TIP: Verwenden Sie ’ ‘, um Quotes in Zeichenketten zu schreiben, oder verwenden Sie die Syntax für Escape-Zeichenketten (E’…’).
FEHLER: ungültige Byte-Sequenz für Kodierung >>LATIN1<<: 0x00

Ich habe auch mal versucht einen Datensatz über das pgAdminIII Query Tool einzugeben, dort kommt folgender Fehler:

FEHLER: Zeichen 0xe2809a in Kodierung »UTF8« hat keine Entsprechung in »LATIN1«
********** Fehler **********
FEHLER: Zeichen 0xe2809a in Kodierung »UTF8« hat keine Entsprechung in »LATIN1«
SQL Status:22P05

So, jetzt steh ich da. Ich habe in meiner Tabelle nämlich ein Bild gespeichert in einem mediumblob Feld, was bei PostgreSQL natürlich ein bytea Feld ist. Genau da meckert er rum, beim Insert. Ich frage mich auch warum das nicht Binär gespeichert wird und warum man bei einem bytea einen konformen Charset verlangt.
Ich habe bei MySQL einmal das aktuelle Charset ausgelesen:

mysql> SHOW VARIABLES LIKE ‘character_set%’;
±-------------------------±--------------------
-+
| Variable_name | Value
|
±-------------------------±--------------------
-+
| character_set_client | latin1
|
| character_set_connection | latin1
|
| character_set_database | latin1
|
| character_set_filesystem | binary
|
| character_set_results | latin1
|
| character_set_server | latin1
|
| character_set_system | utf8

Meine PostgreSQL Datenbank wurde von mir auch auf das Charset latin1 eingestellt. Wo liegt nun das Problem? In der SQL Datei in der Spalte an der das Bild ist sind kryptische Zeichen zu sehen:
É¡»€qÒ€qô£#ÓdÐÖƒÖƒÒŽô\0{bŽØ ‘Þ

ByteA Felder werden mit einem speziellen Escaping “befüllt”. Die nicht druckbaren Werte werden als Backslash und in hexadezimaler Schreibweise abgelegt.

Die Fehler passieren, weil die Datenbank zuerst versucht, deine Daten in das entsprechende Zielencoding umzuwandeln.
Später erst wird festgestellt, dass das ein ByteA ist.

Hi,

danke für den Tip. Aber wieso versucht er erst zu Enkodieren wenn eigentlich an der Struktur schon klar ist was das für ein Feld ist (bytea). Ich werde heute sonst noch 2 Dinge ausprobieren, die ich im Internet aufgeschnappt habe. Zum einen kann man beim mysqldump ein --hex-blob hinzufügen, dann wird aus meinem Zeichenwirrwar im Dump angeblich ein schöner HexBlob, so wie es bei einem PostgreSQL Dump auch standardmäßig ist. Ansonsten hab ich noch bei der Postgre Config Datei einen Eintrag bytea_output gefunden. Könnte der mir vll weiterhelfen? Wie kann ich den verhindern, dass er zuerst Encodieren möchte? Ich habe auch schon einmal alle Encoding angaben in mysqldump und psql(import) weggelassen. Trozdem ging es nich.

Viele Grüße
muRus

PS:
“ByteA Felder werden mit einem speziellen Escaping “befüllt”. Die nicht druckbaren Werte werden als Backslash und in hexadezimaler Schreibweise abgelegt.”

Nicht falschverstehen. Noch hab ich den mysql-Dump, der für Postgre umgeformt wurde. Also in den jetzigen ByteA Feldern sind demnach denke ich noch keine Escape-Zeichen, ausser MySQL verwendet auch welche. Trozdem muss es doch irgendwie gehen die zu übertragen.

Die Escape Sachen von MySQL und PostgreSQL sind nicht kompatibel.
Keine Ahnung, wie du da ohne viel Aufwand drumherum kommst :frowning:

Wenn die Datenbank deine SQL-Anfrage bekommt, versucht sie die in das von dir eingestellte client_encoding umzuwandeln.
Erst danach, viel später, wird diese Anfrage auch geparst bzw. werden die Daten extrahiert, die in die ByteA Spalte sollen.
Davon ist zu dem Zeitpunkt, zu dem die Fehlermeldung auftritt, noch nichts bekannt.

bytea_output ist nur für die Ausgabe von BYTA-Feldern. Traditionell escape, seit 9.0 als Default aber hex. Hex ist kürzer, aber wenn man z.B. DRUPAL nutzt, sollte man es auf escape wieder setzen. Keine Ahnung was die Jungs geraucht haben, aber sie speichern Texte in BYTA-Feldern, welche als hex auf der Webseite dann doch gewöhnungsbedürftig aussehen …

Andreas

Okey danke Jungs soweit,

so wie es aussieht geht es wirklich nicht. Ich habe jetzt eine Funktion in JAVA geschrieben, die mir die Dokumente aus der MySQL DB in einen Ordner kopiert (im Dateinamen die zugehörige ID der Entität) und von dort aus anhand der ID wieder in die neue PostgreSQL DB einspielt. Hätte ich auch früher drauf kommen können ^_^, aber wer rechnet schon mit solchen Hürden. Jetzt habe ich noch ein Problem, dass PostgreSQL meine VARCHAR´s nicht richtig importiert. Ein Eintrag sieht etwa so aus:
INSERT INTO… (…,‘das ist ein Text’,‘C:\das\ist\ein\pfad\’,…);

Er meckert immer bei den Hochkommata´s und bei dem Doppel-Backslash. Ich werde einfach mal testweise eine PostgreSQL TestDB erstellen, einen Text und einen Pfad abspeicher, das ganze dumpen und dann mal angucken wie er dass drin speichert. Es sei denn jemand von euch hat spontan ein Tipp woran es liegt.

Die Hochkommata sehen korrekt aus, bist Du sicher, dass Du uns das korrekt SQL zeigst?

Bzgl. des Backslash: Nimm nur einen und schalte standard_conforming_strings auf true

PostgreSQL: Documentation: Manuals: PostgreSQL 9.0: Version and Platform Compatibility