J'ai passé les 8 dernières heures à essayer d'importer la sortie de 'mysqldump --compatible = postgresql' dans PostgreSQL 8.4.9, et j'ai déjà lu au moins 20 threads différents ici et ailleurs sur ce problème spécifique, mais je n'ai trouvé aucun vraie réponse utilisable qui fonctionne.
Données MySQL 5.1.52 vidées:
mysqldump -u root -p --compatible=postgresql --no-create-info --no-create-db --default-character-set=utf8 --skip-lock-tables rt3 > foo
Serveur PostgreSQL 8.4.9 comme destination
Le chargement des données avec 'psql -U rt_user -f foo' rapporte (beaucoup d'entre eux, voici un exemple):
psql:foo:29: ERROR: invalid byte sequence for encoding "UTF8": 0x00
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".
Selon ce qui suit, il n'y a pas de caractères NULL (0x00) dans le fichier d'entrée.
database-dumps:rcf-temp1# sed 's/\x0/ /g' < foo > nonulls
database-dumps:rcf-temp1# sum foo nonulls
04730 2545610 foo
04730 2545610 nonulls
database-dumps:rcf-temp1# rm nonulls
De même, une autre vérification avec Perl ne montre aucun NULL:
database-dumps:rcf-temp1# perl -ne '/\000/ and print;' foo
database-dumps:rcf-temp1#
Comme l'indique le "CONSEIL" dans l'erreur, j'ai essayé de toutes les manières possibles de définir "client_encoding" sur "UTF8", et je réussis, mais cela n'a aucun effet sur la résolution de mon problème.
database-dumps:rcf-temp1# psql -U rt_user --variable=client_encoding=utf-8 -c "SHOW client_encoding;" rt3
client_encoding
-----------------
UTF8
(1 row)
database-dumps:rcf-temp1#
Parfait, pourtant:
database-dumps:rcf-temp1# psql -U rt_user -f foo --variable=client_encoding=utf-8 rt3
...
psql:foo:29: ERROR: invalid byte sequence for encoding "UTF8": 0x00
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".
...
À l'exception de la bonne réponse «Selon Hoyle», qui serait fantastique à entendre, et sachant que je ne me soucie vraiment pas de conserver des caractères non ASCII pour ces données rarement référencées, quelles suggestions avez-vous?
Mise à jour: j'obtiens la même erreur avec une version ASCII uniquement du même fichier de vidage au moment de l'importation. Vraiment ahurissant:
database-dumps:rcf-temp1# # convert any non-ASCII character to a space
database-dumps:rcf-temp1# perl -i.bk -pe 's/[^[:ascii:]]/ /g;' mysql5-dump.sql
database-dumps:rcf-temp1# sum mysql5-dump.sql mysql5-dump.sql.bk
41053 2545611 mysql5-dump.sql
50145 2545611 mysql5-dump.sql.bk
database-dumps:rcf-temp1# cmp mysql5-dump.sql mysql5-dump.sql.bk
mysql5-dump.sql mysql5-dump.sql.bk differ: byte 1304850, line 30
database-dumps:rcf-temp1# # GOOD!
database-dumps:rcf-temp1# psql -U postgres -f mysql5-dump.sql --variable=client_encoding=utf-8 rt3
...
INSERT 0 416
psql:mysql5-dump.sql:30: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 455
INSERT 0 424
INSERT 0 483
INSERT 0 447
INSERT 0 503
psql:mysql5-dump.sql:36: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 502
INSERT 0 507
INSERT 0 318
INSERT 0 284
psql:mysql5-dump.sql:41: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 382
INSERT 0 419
INSERT 0 247
psql:mysql5-dump.sql:45: ERROR: invalid byte sequence for encoding "UTF8": 0x00
HINT: This error can also happen if the byte sequence does not match the encod.
INSERT 0 267
INSERT 0 348
^C
L'un des tableaux en question est défini comme:
Table "public.attachments"
Column | Type | Modifie
-----------------+-----------------------------+--------------------------------
id | integer | not null default nextval('atta)
transactionid | integer | not null
parent | integer | not null default 0
messageid | character varying(160) |
subject | character varying(255) |
filename | character varying(255) |
contenttype | character varying(80) |
contentencoding | character varying(80) |
content | text |
headers | text |
creator | integer | not null default 0
created | timestamp without time zone |
Indexes:
"attachments_pkey" PRIMARY KEY, btree (id)
"attachments1" btree (parent)
"attachments2" btree (transactionid)
"attachments3" btree (parent, transactionid)
Je n'ai pas la liberté de changer le type pour aucune partie du schéma DB. Cela interromprait probablement les futures mises à niveau du logiciel , etc.
La colonne susceptible de poser problème est le «contenu» de type «texte» (peut-être aussi dans d'autres tableaux). Comme je le sais déjà par des recherches précédentes, PostgreSQL n'autorisera pas NULL dans les valeurs de 'texte'. Cependant, veuillez voir ci-dessus où sed et Perl ne montrent aucun caractère NULL, puis plus bas où je supprime tous les caractères non ASCII de tout le fichier de vidage, mais il barfs toujours.
head -29 foo | tail -1 | cat -v
pourrait être utile.