web-dev-qa-db-fra.com

séquence d'octets non valide pour l'encodage "UTF8"

Je suis j'essaie d'importer des données dans ma base de données. J'ai donc créé une table temporaire,

create temporary table tmp(pc varchar(10), lat decimal(18,12), lon decimal(18,12), city varchar(100), prov varchar(2));

Et maintenant j'essaie d'importer les données ,

 copy tmp from '/home/mark/Desktop/Canada.csv' delimiter ',' csv

Mais alors j'obtiens l'erreur,

ERROR:  invalid byte sequence for encoding "UTF8": 0xc92c

Comment puis-je résoudre ce problème? Dois-je modifier le codage de toute ma base de données (si oui, comment?) Ou puis-je modifier uniquement le codage de ma table tmp? Ou devrais-je essayer de changer l'encodage du fichier?

103
mpen

Si vous devez stocker des données UTF8 dans votre base de données, vous avez besoin d’une base de données qui accepte UTF8. Vous pouvez vérifier le codage de votre base de données dans pgAdmin. Il suffit de cliquer avec le bouton droit sur la base de données et de sélectionner "Propriétés".

Mais cette erreur semble vous indiquer qu'il existe des données UTF8 non valides dans votre fichier source. Cela signifie que l'utilitaire copy a détecté ou supposé que vous lui fournissez un fichier UTF8.

Si vous utilisez une variante d’Unix, vous pouvez vérifier l’encodage (plus ou moins) avec l’utilitaire file .

$ file yourfilename
yourfilename: UTF-8 Unicode English text

(Je pense que cela fonctionnera aussi sur les Mac du terminal.) Vous ne savez pas comment faire cela sous Windows.

Si vous utilisez le même utilitaire sur un fichier provenant de systèmes Windows (c’est-à-dire un fichier codé en pas codé en UTF8), il se présentera probablement comme ceci:

$ file yourfilename
yourfilename: ASCII text, with CRLF line terminators

Si les choses restent étranges, vous pouvez essayer de convertir vos données d'entrée en un codage connu, de modifier le codage de votre client, ou les deux. (Nous sommes vraiment en train de repousser les limites de ma connaissance des encodages.)

Vous pouvez utiliser l'utilitaire iconv pour modifier le codage des données d'entrée.

iconv -f original_charset -t utf-8 originalfile > newfile

Vous pouvez modifier le codage psql (le client) en suivant les instructions de Jeu de caractères . Sur cette page, recherchez l'expression "Pour activer la conversion automatique des jeux de caractères".

psql=# copy tmp from '/path/to/file.csv' with delimiter ',' csv header encoding 'windows-1251';

L'ajout de l'option encoding a fonctionné dans mon cas.

43
Nobu

Apparemment, je peux juste régler l'encodage à la volée,

 set client_encoding to 'latin1'

Et puis réexécutez la requête. Je ne sais pas quel encodage je devrais utiliser.


latin1 a rendu les caractères lisibles, mais la plupart des caractères accentués étaient en majuscules là où ils n'auraient pas dû l'être. J'ai supposé que cela était dû à un mauvais encodage, mais je pense que c'est en fait les données qui étaient mauvaises. J'ai fini par conserver le codage latin1, mais en pré-traitant les données et en corrigeant les problèmes de casse.

10
mpen

Si vous êtes prêt à abandonner les caractères non convertibles, vous pouvez utiliser -c flag

iconv -c -t utf8 filename.csv > filename.utf8.csv

puis copiez-les sur votre table

6
Abdellah Alaoui

Cette erreur signifie que le codage des enregistrements dans le fichier est différent en ce qui concerne la connexion. Dans ce cas, iconv peut renvoyer l'erreur, parfois même malgré le drapeau // IGNORE: 

iconv -f ASCII -t utf-8 // IGNORE <b.txt> /a.txt

iconv: séquence d'entrée illégale à la position (un certain nombre) 

L'astuce consiste à trouver des caractères incorrects et à les remplacer. Pour le faire sous Linux, utilisez l'éditeur "vim": 

vim (votre fichier texte), appuyez sur "ESC": bouton et tapez ": goto (numéro retourné par iconv)"

Pour rechercher des caractères non ASCII, vous pouvez utiliser la commande suivante:

grep --color = 'auto' -P "[\ x80-\xFF]"  

Si vous supprimez des caractères incorrects, veuillez vérifier si vous avez vraiment besoin de convertir votre fichier: le problème est probablement déjà résolu.

6
Yuri Levinsky

Cela dépend du type de machine/d'encodage généré par votre fichier d'importation.

Si vous l'obtenez à partir d'une version anglaise ou européenne occidentale de Windows, votre meilleur pari est probablement de le définir sur 'WIN1252'. Si vous l’obtenez d’une autre source, consultez la liste des codages de caractères ici:

http://www.postgresql.org/docs/8.3/static/multibyte.html

Si vous l'obtenez d'un Mac, vous devrez peut-être d'abord l'exécuter via l'utilitaire "iconv" pour le convertir de MacRoman à UTF-8.

4
BobG

Eh bien, je faisais face au même problème. Et ce qui a résolu mon problème est le suivant:

Dans Excel, cliquez sur Enregistrer sous . À partir de type, sélectionnez .csv Cliquez sur Outils . Choisissez ensuite les options Web dans la liste déroulante . Sous Encodage onglet, enregistrez le document au format Unicode (UTF-8) . Cliquez sur OK . Enregistrez le fichier. TERMINÉ !

4
Vishal Chhatwani

J'ai eu le même problème et j'ai trouvé une solution intéressante ici: http://blog.e-Shell.org/134

Cela est dû à une incompatibilité dans les codages de votre base de données, certainement parce que la base de données d'où vous avez récupéré le vidage SQL a été codée en tant que SQL_ASCII alors que la nouvelle est codée en tant que UTF8. .. Recode est un petit outil du projet GNU qui vous permet de modifier à la volée l'encodage d'un fichier donné.

Je viens donc de recoder le fichier de vidage avant de le lire:

postgres> gunzip -c /var/backups/pgall_b1.Zip | recode iso-8859-1..u8 | psql test

Dans les systèmes Debian ou Ubuntu, recode peut être installé via un package.

2
Ed Doerr

Vous pouvez remplacer le caractère barre oblique inverse par, par exemple, un caractère de canal par sed.

sed -i -- 's/\\/|/g' filename.txt
2
Richard Greenwood

Pour Python, vous devez utiliser

Classe pg8000.types.Bytea (str) Bytea est une classe dérivée de str mappée sur un tableau d'octets PostgreSQL.

ou

Pg8000.Binary (valeur) Construire un objet contenant des données binaires.

1
vrn

Petit exemple pour résoudre ce problème en PHP-

$val = "E'\377'";
iconv(mb_detect_encoding($val, mb_detect_order(), true), "UTF-8", $val);

Détail de l’erreur: La base de données POSTGRES ne gérant pas d’autres caractères que les caractères UTF-8 lorsque nous essayons de transmettre les entrées susmentionnées à une colonne, elle donne l’erreur "séquence d’octets non valide pour le codage" UTF8 ": 0xab".

Il suffit donc de convertir cette valeur en UTF-8 avant son insertion dans la base de données POSTGRES.

1
Nneha Sachan
copy tablename from 'filepath\filename' DELIMITERS '=' ENCODING 'WIN1252';

vous pouvez essayer ceci pour gérer le codage UTF8.

1
Rishi jha

Cette erreur peut se produire si les données d'entrée contiennent le caractère d'échappement lui-même. Par défaut, le caractère d'échappement est le symbole "\". Si votre texte d'entrée contient le caractère "\", essayez de modifier la valeur par défaut à l'aide de l'option ESCAPE.

1
jaasco

Il est également très possible avec cette erreur que le champ soit crypté en place. Assurez-vous de consulter le bon tableau. Dans certains cas, les administrateurs créeront une vue non chiffrée que vous pourrez utiliser à la place. J'ai récemment rencontré un problème très similaire.

0
Josh Barton

Ouvrez le fichier CSV de Notepad ++. Choisissez le menu Encoding\Encoding in UTF-8, puis corrigez quelques cellules manuellement. 

Puis réessayez d'importer.

0
foobarfuu

J'ai eu la même erreur lorsque j'essayais de copier un csv généré par Excel dans une table Postgres (tous sur un Mac). Voici comment je l'ai résolu:

1) Ouvrez le fichier dans Atom (le IDE que j'utilise)

2) Faites un changement insignifiant dans le fichier. Enregistrez le fichier. Annuler le changement. Sauvegarder à nouveau.

Presto! La commande de copie a fonctionné maintenant. 

(Je pense que Atom l'a sauvegardé dans un format qui a fonctionné) 

0
Anupam