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.
la source
head -29 foo | tail -1 | cat -v
pourrait être utile.Réponses:
Un ou plusieurs de ces champs de caractères / texte PEUVENT avoir 0x00 pour son contenu.
Essayez ce qui suit:
Si cela renvoie une seule ligne, essayez de mettre à jour ces champs de caractères / texte avec:
Ensuite, essayez un autre MYSQLDUMP ... (et la méthode d'importation PostgreSQL).
la source
colname LIKE concat('%', 0x00, '%')
. Je les ai trouvés dans des champs contenant des tableaux PHP sérialisés.J'ai eu le même problème avec MySQL version 5.0.51 et Postgres version 9.3.4.0. J'ai résolu le problème de la "séquence d'octets invalide pour l'encodage" UTF8 ": 0x00" après avoir vu le commentaire de Daniel Vérité selon lequel "mysqldump en mode postgresql videra les octets nuls en tant que \ 0 dans les chaînes, donc vous voudrez probablement rechercher cette séquence de caractères."
Effectivement, un grep a finalement révélé les caractères NULL.
J'ai remplacé les caractères NULL à l'aide de la commande suivante
Postgres a ensuite réussi à charger dump.sql
la source
Vous pouvez obtenir cette erreur sans octet NULL ni caractère non ascii dans le fichier. Exemple dans une base de données utf8:
donnera:
mysqldump en mode postgresql videra les octets nuls en tant que \ 0 dans les chaînes, donc vous voudrez probablement rechercher cette séquence de caractères.
la source
Je me souviens à moitié d'un problème comme celui-ci. Je pense que j'ai fini par migrer le schéma, puis vider les données au format csv et charger les données du fichier csv. Je me souviens avoir dû mettre à jour le fichier csv (en utilisant des outils Unix comme sed ou unixtodos) ou utiliser open office calc (excell) pour corriger certains éléments qui étaient des erreurs lors de l'étape d'importation - cela pourrait être aussi simple que d'ouvrir et de réenregistrer le fichier.
la source