ungültige Bytesequenz für die Codierung von "UTF8"

124

Ich versuche, einige Daten in meine Datenbank zu importieren . Also habe ich eine temporäre Tabelle erstellt,

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

Und jetzt versuche ich die Daten zu importieren ,

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

Aber dann bekomme ich den Fehler,

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

Wie behebe ich das? Muss ich die Codierung meiner gesamten Datenbank ändern (wenn ja, wie?) Oder kann ich nur die Codierung meiner tmpTabelle ändern ? Oder sollte ich versuchen, die Codierung der Datei zu ändern?

mpen
quelle
Ändern Sie die Codierungsoption beim Import. Ich habe meine auf "Windows-1251" eingestellt und es hat ohne Beanstandung funktioniert.
Brian D
1
Danke @BrianD, ich war auch mit diesem Problem konfrontiert und das hat bei mir funktioniert.
Gouravkr

Antworten:

109

Wenn Sie UTF8-Daten in Ihrer Datenbank speichern müssen, benötigen Sie eine Datenbank, die UTF8 akzeptiert. Sie können die Codierung Ihrer Datenbank in pgAdmin überprüfen. Klicken Sie einfach mit der rechten Maustaste auf die Datenbank und wählen Sie "Eigenschaften".

Dieser Fehler scheint jedoch darauf hinzudeuten, dass Ihre Quelldatei einige ungültige UTF8-Daten enthält. Das bedeutet, dass das copyDienstprogramm erkannt oder vermutet hat, dass Sie ihm eine UTF8-Datei zuführen.

Wenn Sie unter einer Unix-Variante arbeiten, können Sie die Codierung (mehr oder weniger) mit dem fileDienstprogramm überprüfen .

$ file yourfilename
yourfilename: UTF-8 Unicode English text

(Ich denke, das funktioniert auch auf Macs im Terminal.) Ich bin mir nicht sicher, wie ich das unter Windows machen soll.

Wenn Sie dasselbe Dienstprogramm für eine Datei verwenden, die von Windows-Systemen stammt ( dh eine Datei, die nicht in UTF8 codiert ist), wird wahrscheinlich Folgendes angezeigt:

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

Wenn die Dinge merkwürdig bleiben, können Sie versuchen, Ihre Eingabedaten in eine bekannte Codierung zu konvertieren, die Codierung Ihres Clients zu ändern oder beides. (Wir erweitern wirklich die Grenzen meines Wissens über Codierungen.)

Mit dem iconvDienstprogramm können Sie die Codierung der Eingabedaten ändern.

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

Sie können die psql-Codierung (die Client-Codierung) gemäß den Anweisungen zur Zeichensatzunterstützung ändern . Suchen Sie auf dieser Seite nach dem Ausdruck "So aktivieren Sie die automatische Zeichensatzkonvertierung".

Mike Sherrill 'Cat Recall'
quelle
3
Sagt, die Datei ist ASCII, enthält aber Zeichen mit Akzent, also muss das falsch sein?
Mpen
2
Ich werde diese Antwort akzeptieren, aber ich denke, das Problem lag tatsächlich bei den Daten (aktualisiertes Q).
Mpen
1
Ich fand das hilfreich, danke. Übrigens läuft es auch auf OS X-Terminals
Raul Rene
1
Das hat bei mir funktioniert, aber auf etwas andere Weise. Der Befehl "iconv" hat meine Datei tatsächlich bombardiert, aber genau dort, wo das Problem lag - eine seltsame Art von "-" Zeichen. Wie auch immer, ich habe das entfernt und meine Datei konnte in postgres geladen werden. Danke für den Tipp!
trip0d199
1
Nur um anderen und den Suchmaschinen zu helfen: Dies funktioniert zum Konvertieren eines Stripe CSV-Exports mit unlesbaren Zeichen zurück in UTF-8: "iconv -f ISO-8859-15 -t utf-8 customers.csv> customers-utf8.csv"
sscarduzio
57
psql=# copy tmp from '/path/to/file.csv' with delimiter ',' csv header encoding 'windows-1251';

Das Hinzufügen einer encodingOption hat in meinem Fall funktioniert.

Nobu
quelle
1
Es wird fehlerfrei abgeschlossen und kann nützliche Ergebnisse liefern oder auch nicht. Sie müssen die beabsichtigte Codierung der Daten kennen.
Jasen
1
Wie hat die obige Abfrage in meinem Szenario funktioniert? Ich habe CSV-Datei mit UTF8 und DB mit UTF8 codiert.
Ajay Takur
14

Anscheinend kann ich die Kodierung einfach im laufenden Betrieb einstellen ,

 set client_encoding to 'latin1'

Führen Sie dann die Abfrage erneut aus. Ich bin mir nicht sicher, welche Codierung ich verwenden soll.


latin1machte die Zeichen lesbar, aber die meisten Zeichen mit Akzent waren in Großbuchstaben geschrieben, wo sie nicht hätten sein sollen. Ich nahm an, dass dies auf eine schlechte Codierung zurückzuführen war, aber ich denke, es sind tatsächlich die Daten, die nur schlecht waren. Am Ende habe ich die Latin1-Codierung beibehalten, aber die Daten vorverarbeitet und die Gehäuseprobleme behoben.

mpen
quelle
Interessanterweise habe ich den Fehler bei einer SELECT-Anweisung erhalten! Dies löste es, weil es mein psql- Client war , der den Fehler gab, nicht die Datenbank selbst. (Was die Daten an erster Stelle abgelehnt hätte, hätte die Codierung verboten.)
Wildcard
14

Wenn Sie nicht konvertierbare Zeichen verwerfen können, können Sie -cflag verwenden

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

und kopieren Sie sie dann auf Ihren Tisch

Abdellah Alaoui
quelle
Auf dem Mac war es iconv -c -t UTF-8 filename.csv > filename.utf8.csvfür mich
Michael
8

Dieser Fehler bedeutet, dass die Codierung der Datensätze in der Datei in Bezug auf die Verbindung unterschiedlich ist. In diesem Fall kann iconv den Fehler zurückgeben, manchmal sogar trotz des // IGNORE-Flags:

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

iconv: unzulässige Eingabesequenz an Position (eine Nummer)

Der Trick besteht darin, falsche Zeichen zu finden und zu ersetzen. Verwenden Sie dazu unter Linux den "vim" -Editor:

vim (Ihre Textdatei), drücken Sie die Taste "ESC": und geben Sie ": goto (von iconv zurückgegebene Nummer)" ein.

Um Nicht-ASCII-Zeichen zu finden, können Sie den folgenden Befehl verwenden:

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

Wenn Sie falsche Zeichen entfernen, überprüfen Sie bitte, ob Sie Ihre Datei wirklich konvertieren müssen: Wahrscheinlich ist das Problem bereits behoben.

Yuri Levinsky
quelle
iconv -c -f utf8 -t utf8//IGNORE < dirty.txt > clean.txt
Jasen
5

Führen Sie die folgenden Schritte aus, um dieses Problem in pgadmin zu beheben:

  1. SET client_encoding = 'ISO_8859_5';

  2. COPY tablename(column names) FROM 'D:/DB_BAK/csvfilename.csv' WITH DELIMITER ',' CSV ;

Ramesh R.
quelle
4

Dies hängt davon ab, welche Art von Maschine / Codierung Ihre Importdatei generiert hat.

Wenn Sie es von einer englischen oder westeuropäischen Version von Windows erhalten, ist es wahrscheinlich am besten, es auf "WIN1252" zu setzen. Wenn Sie es aus einer anderen Quelle beziehen, konsultieren Sie die Liste der Zeichenkodierungen hier:

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

Wenn Sie es von einem Mac erhalten, müssen Sie es möglicherweise zuerst über das Dienstprogramm "iconv" ausführen, um es von MacRoman nach UTF-8 zu konvertieren.

BobG
quelle
4

Nun, ich hatte das gleiche Problem. Und was mein Problem gelöst hat, ist Folgendes:

Klicken Sie in Excel auf Speichern unter. Wählen Sie unter Dateityp die Option .csv. Klicken Sie auf Extras . Wählen Sie dann Weboptionen aus der Dropdown-Liste. Unter Encoding Registerkarte speichern Sie das Dokument als Unicode (UTF-8) . OK klicken. Speicher die Datei. GETAN !

Vishal Chhatwani
quelle
3

Ich hatte das gleiche Problem und fand hier eine gute Lösung: http://blog.e-shell.org/134

Dies wird durch eine Nichtübereinstimmung in Ihren Datenbankcodierungen verursacht, sicherlich weil die Datenbank, von der Sie den SQL-Speicherauszug erhalten haben, als SQL_ASCII codiert wurde, während die neue als UTF8 codiert wurde. .. Recode ist ein kleines Tool aus dem GNU-Projekt, mit dem Sie die Codierung einer bestimmten Datei im laufenden Betrieb ändern können.

Also habe ich das Dumpfile einfach neu codiert, bevor ich es wiedergegeben habe:

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

In Debian- oder Ubuntu-Systemen kann die Neukodierung per Paket installiert werden.

Ed Doerr
quelle
2

Sie können das Backslash-Zeichen beispielsweise durch ein Pipe-Zeichen durch sed ersetzen.

sed -i -- 's/\\/|/g' filename.txt
Richard Greenwood
quelle
2
copy tablename from 'filepath\filename' DELIMITERS '=' ENCODING 'WIN1252';

Sie können dies versuchen, um die UTF8-Codierung zu handhaben.

Rishi jha
quelle
2

Kurzes Beispiel zur Lösung dieses Problems in PHP-

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

Fehlerdetail: Da die POSTGRES-Datenbank keine anderen als UTF-8-Zeichen verarbeitet, wenn wir versuchen, die oben angegebenen Eingaben an eine Spalte zu übergeben, wird der Fehler "ungültige Bytesequenz für die Codierung von" UTF8 ": 0xab" angezeigt.

Konvertieren Sie diesen Wert einfach in UTF-8, bevor Sie ihn in die POSTGRES-Datenbank einfügen.

Nneha Sachan
quelle
2

Ich hatte das gleiche Problem: Meine Datei wurde nicht als UTF-8 codiert. Ich habe es gelöst, indem ich die Datei mit Notepad ++ geöffnet und die Codierung der Datei geändert habe.

Gehen Sie zu "Codierung" und wählen Sie "In UTF-8 konvertieren". Änderungen speichern und das ist alles!

Francisco Javier Snchez Sabido
quelle
1

Dieser Fehler kann auftreten, wenn die Eingabedaten das Escapezeichen selbst enthalten. Standardmäßig ist das Escape-Zeichen das Symbol "\". Wenn Ihr Eingabetext also das Zeichen "\" enthält, versuchen Sie, den Standardwert mit der Option ESCAPE zu ändern.

jaasco
quelle
1

Für Python müssen Sie verwenden

Klasse pg8000.types.Bytea (str) Bytea ist eine von str abgeleitete Klasse, die einem PostgreSQL-Byte-Array zugeordnet ist.

oder

Pg8000.Binary (Wert) Konstruiert ein Objekt, das Binärdaten enthält.

vrn
quelle
1

Ich bin unter Windows auf dieses Problem gestoßen, als ich ausschließlich mit psql gearbeitet habe (keine grafischen Tools). Um dieses Problem zu beheben, ändern Sie die Standardcodierung von psql (Client) dauerhaft, um sie an die Standardcodierung des PostgreSQL-Servers anzupassen. Führen Sie den folgenden Befehl in CMD oder Powershell aus:

setx PGCLIENTENCODING UTF8

Schließen Sie die Eingabeaufforderung / Powershell und öffnen Sie sie erneut, damit die Änderung wirksam wird.

Ändern Sie die Codierung der Sicherungsdatei von Unicode in UTF8, indem Sie sie mit Notepad öffnen und zu Datei -> Speichern unter gehen. Ändern Sie die Dropdown-Liste Codierung von Unicode in UTF8. (Ändern Sie auch den Typ Speichern unter von Textdokumenten (.txt) in Alle Dateien, um zu vermeiden, dass die Erweiterung .txt zum Namen Ihrer Sicherungsdatei hinzugefügt wird.) Sie sollten jetzt in der Lage sein, Ihr Backup wiederherzustellen.

Hehe
quelle
0

Mit diesem Fehler ist es auch sehr gut möglich, dass das Feld an Ort und Stelle verschlüsselt wird. Stellen Sie sicher, dass Sie sich die richtige Tabelle ansehen. In einigen Fällen erstellen Administratoren eine unverschlüsselte Ansicht, die Sie stattdessen verwenden können. Ich bin kürzlich auf ein sehr ähnliches Problem gestoßen.

Josh Barton
quelle
0

Ich habe den gleichen Fehler erhalten, als ich versucht habe, eine von Excel generierte CSV in eine Postgres-Tabelle zu kopieren (alles auf einem Mac). So habe ich es gelöst:

1) Öffnen Sie die Datei in Atom (die von mir verwendete IDE).

2) Nehmen Sie eine unbedeutende Änderung in der Datei vor. Speicher die Datei. Machen Sie die Änderung rückgängig. Speichern Sie erneut.

Presto! Der Kopierbefehl hat jetzt funktioniert.

(Ich denke, Atom hat es in einem Format gespeichert, das funktioniert hat)

Anupam
quelle
0

Öffnen Sie die Datei CSV mit Notepad ++. Wählen Sie Menü Encoding\ Encoding in UTF-8und korrigieren Sie einige Zellen manuell.

Versuchen Sie dann erneut zu importieren.

Mach Nhu Vy
quelle
0

Wenn Ihre CSV aus SQL Server exportiert werden soll, ist sie sehr groß und enthält Unicode-Zeichen. Sie können sie exportieren, indem Sie die Codierung wie folgt festlegen UTF-8:

Right-Click DB > Tasks > Export > 'SQL Server Native Client 11.0' >> 'Flat File Destination > File name: ... > Code page: UTF-8 >> ...

Auf der nächsten Seite werden Sie gefragt, ob Sie Daten aus einer Tabelle kopieren oder eine Abfrage schreiben möchten. Wenn Sie charoder varcharDatentypen in Ihrer Tabelle haben, wählen Sie die Abfrageoption und wandeln Sie diese Spalten als nvarchar(max). Wenn z. B. myTablezwei Spalten vorhanden sind, in denen sich die erste varcharund die zweite befinden int, wirke ich die erste auf nvarchar:

select cast (col1 as nvarchar(max)) col1
       , col2
from myTable
LoMaPh
quelle