nieprawidłowa sekwencja bajtów do kodowania „UTF8”

125

Ja próbuje zaimportować dane do mojej bazy danych. Więc utworzyłem tymczasową tabelę,

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

Teraz próbuję zaimportować dane ,

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

Ale potem pojawia się błąd,

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

Jak to naprawić? Czy muszę zmienić kodowanie całej mojej bazy danych (jeśli tak, w jaki sposób?), Czy mogę zmienić tylko kodowanie mojej tmptabeli? Czy powinienem spróbować zmienić kodowanie pliku?

mpen
źródło
zmienić opcję kodowania podczas importu. Ustawiłem mój na "Windows-1251" i działał bez zarzutu.
Brian D
1
Dzięki @BrianD, ja też miałem do czynienia z tym problemem i to zadziałało.
gouravkr

Odpowiedzi:

110

Jeśli chcesz przechowywać dane UTF8 w swojej bazie danych, potrzebujesz bazy danych, która akceptuje UTF8. Możesz sprawdzić kodowanie swojej bazy danych w pgAdmin. Kliknij bazę danych prawym przyciskiem myszy i wybierz „Właściwości”.

Ale ten błąd wydaje się informować, że w pliku źródłowym są nieprawidłowe dane UTF8. Oznacza to, że copynarzędzie wykryło lub zgadło, że podajesz mu plik UTF8.

Jeśli pracujesz pod jakimś wariantem Uniksa, możesz sprawdzić kodowanie (mniej więcej) za pomocą filenarzędzia.

$ file yourfilename
yourfilename: UTF-8 Unicode English text

(Myślę, że to zadziała również na komputerach Mac w terminalu.) Nie wiem, jak to zrobić w systemie Windows.

Jeśli użyjesz tego samego narzędzia do pliku pochodzącego z systemu Windows (czyli pliku, który nie jest zakodowany w UTF8), prawdopodobnie pokaże coś takiego:

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

Jeśli sprawy pozostaną dziwne, możesz spróbować przekonwertować dane wejściowe na znane kodowanie, zmienić kodowanie klienta lub jedno i drugie. (Naprawdę przekraczamy granice mojej wiedzy na temat kodowania).

Możesz użyć iconvnarzędzia do zmiany kodowania danych wejściowych.

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

Możesz zmienić kodowanie psql (klienta), postępując zgodnie z instrukcjami dotyczącymi obsługi zestawu znaków . Na tej stronie wyszukaj frazę „Aby włączyć automatyczną konwersję zestawu znaków”.

Mike Sherrill `` Cat Recall ''
źródło
3
Mówi, że plik jest ASCII, ale zawiera znaki akcentowane, więc to musi być błąd?
mpen
2
Zaakceptuję tę odpowiedź, ale myślę, że problem faktycznie dotyczył danych (zaktualizowane Q).
mpen
1
Uważam, że to pomocne, dzięki. Nawiasem mówiąc, działa również na terminalach OS X
Raul Rene
1
U mnie to zadziałało, ale w nieco inny sposób. Polecenie "iconv" faktycznie zbombardowało mój plik, ale zrobiło to dokładnie tam, gdzie był problem - jakiś dziwny rodzaj "-" znaku. W każdym razie usunąłem to i mój plik był w stanie załadować do postgresów. Dzięki za wskazówkę!
trip0d199
1
Aby pomóc innym i wyszukiwarkom: to działa w przypadku konwersji eksportu Stripe CSV z nieczytelnymi znakami z powrotem do 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';

Dodanie encodingopcji zadziałało w moim przypadku.

Nobu
źródło
1
zakończy się bez błędów, może, ale nie musi, dać użyteczne wyniki. musisz znać zamierzone kodowanie danych.
Jasen
1
W moim scenariuszu, jak zadziałało powyższe zapytanie? Mam plik csv zakodowany w UTF8 i DB zakodowany w UTF8.
Ajay Takur
14

Najwyraźniej mogę po prostu ustawić kodowanie w locie,

 set client_encoding to 'latin1'

Następnie ponownie uruchom zapytanie. Nie wiem jednak, jakiego kodowania powinienem używać.


latin1sprawiło, że znaki były czytelne, ale większość znaków akcentowanych była pisana dużymi literami tam, gdzie nie powinny. Zakładałem, że jest to spowodowane złym kodowaniem, ale myślę, że w rzeczywistości dane były po prostu złe. Ostatecznie zachowałem kodowanie latin1, ale wstępnie przetworzyłem dane i rozwiązałem problemy z obudową.

mpen
źródło
Co ciekawe, wystąpił błąd w instrukcji SELECT! To rozwiązało problem, ponieważ to mój klient psql podał błąd, a nie sama baza danych. (Który odrzuciłby dane w pierwszej kolejności, gdyby kodowanie zabroniło tego.)
Wildcard
14

Jeśli nie masz nic przeciwko odrzucaniu znaków, których nie można zamienić, możesz użyć -cflagi

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

a następnie skopiuj je do swojego stołu

Abdellah Alaoui
źródło
Na Macu to było iconv -c -t UTF-8 filename.csv > filename.utf8.csvdla mnie
Michael.
8

Ten błąd oznacza, że ​​kodowanie rekordów w pliku różni się w zależności od połączenia. W tym przypadku iconv może zwrócić błąd, czasami nawet pomimo flagi // IGNORE:

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

iconv: niedozwolona sekwencja wprowadzania na pozycji (pewna liczba)

Sztuczka polega na znalezieniu nieprawidłowych znaków i zastąpieniu ich. Aby to zrobić na Linuksie użyj edytora "vim":

vim (twój plik tekstowy), naciśnij przycisk "ESC": i wpisz ": goto (liczba zwrócona przez iconv)"

Aby znaleźć znaki spoza ASCII, możesz użyć następującego polecenia:

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

Jeśli usuniesz nieprawidłowe znaki, sprawdź, czy naprawdę potrzebujesz przekonwertować plik: prawdopodobnie problem został już rozwiązany.

Yuri Levinsky
źródło
iconv -c -f utf8 -t utf8//IGNORE < dirty.txt > clean.txt
Jasen
5

wykonaj poniższe kroki, aby rozwiązać ten problem w pgadmin:

  1. SET client_encoding = 'ISO_8859_5';

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

Ramesh R
źródło
4

To zależy od typu maszyny / kodowania, które wygenerowało plik importu.

Jeśli otrzymujesz go z angielskiej lub zachodnioeuropejskiej wersji systemu Windows, najlepszym rozwiązaniem jest prawdopodobnie ustawienie „WIN1252”. Jeśli otrzymujesz go z innego źródła, zapoznaj się z listą kodowań znaków tutaj:

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

Jeśli pobierasz go z komputera Mac, być może będziesz musiał najpierw uruchomić go przez narzędzie „iconv”, aby przekonwertować go z MacRoman na UTF-8.

BobG
źródło
4

Cóż, miałem ten sam problem. A to, co rozwiązało mój problem, to:

W programie Excel kliknij Zapisz jako. Z Zapisz jako typ wybierz .csv Kliknij Narzędzia . Następnie wybierz opcje internetowe z rozwijanej listy. Na karcie Kodowanie zapisz dokument w formacie Unicode (UTF-8) . Kliknij OK. Zapisz plik. GOTOWE !

Vishal Chhatwani
źródło
3

Miałem ten sam problem i znalazłem fajne rozwiązanie tutaj: http://blog.e-shell.org/134

Jest to spowodowane niedopasowaniem kodowania bazy danych, z pewnością dlatego, że baza danych, z której pobrałeś zrzut SQL, została zakodowana jako SQL_ASCII, podczas gdy nowa jest zakodowana jako UTF8. .. Recode to małe narzędzie z projektu GNU, które umożliwia zmianę w locie kodowania danego pliku.

Więc po prostu przekodowałem plik zrzutu przed odtworzeniem go:

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

W systemach Debian lub Ubuntu recode można zainstalować za pośrednictwem pakietu.

Ed Doerr
źródło
2

Znak ukośnika odwrotnego można zastąpić, na przykład pionową kreską, sedem.

sed -i -- 's/\\/|/g' filename.txt
Richarda Greenwooda
źródło
2
copy tablename from 'filepath\filename' DELIMITERS '=' ENCODING 'WIN1252';

możesz spróbować obsługiwać kodowanie UTF8.

Rishi jha
źródło
2

Krótki przykład rozwiązania tego problemu w PHP-

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

Szczegóły błędu: Ponieważ baza danych POSTGRES nie obsługuje znaków innych niż UTF-8, kiedy próbujemy przekazać powyższe dane wejściowe do kolumny, daje to błąd „nieprawidłowa sekwencja bajtów do kodowania„ UTF8 ”: 0xab”.

Więc po prostu przekonwertuj tę wartość na UTF-8 przed wstawieniem do bazy danych POSTGRES.

Nneha Sachan
źródło
2

Miałem ten sam problem: mój plik nie został zakodowany jako UTF-8. Rozwiązałem to, otwierając plik za pomocą notatnika ++ i zmieniając kodowanie pliku.

Przejdź do „Kodowania” i wybierz „Konwertuj na UTF-8”. Zapisz zmiany i to wszystko!

Francisco Javier Snchez Sabido
źródło
1

Ten błąd może wystąpić, jeśli dane wejściowe zawierają same znaki zmiany znaczenia. Domyślnym znakiem zmiany znaczenia jest symbol „\”, więc jeśli wprowadzany tekst zawiera znak „\” - spróbuj zmienić wartość domyślną za pomocą opcji ESCAPE.

jaasco
źródło
1

W przypadku Pythona musisz użyć

Klasa pg8000.types.Bytea (str) Bytea jest klasą pochodną typu str, która jest odwzorowywana na tablicę bajtów PostgreSQL.

lub

Pg8000.Binary (wartość) Skonstruuj obiekt przechowujący dane binarne.

vrn
źródło
1

Napotkałem ten problem pod Windows podczas pracy wyłącznie z psql (bez narzędzi graficznych). Aby rozwiązać ten problem, na stałe zmień domyślne kodowanie psql (klient), aby pasowało do domyślnego kodowania serwera PostgreSQL. Uruchom następujące polecenie w CMD lub Powershell:

setx PGCLIENTENCODING UTF8

Zamknij i ponownie otwórz wiersz polecenia / PowerShell, aby zmiana zaczęła obowiązywać.

Zmień kodowanie pliku kopii zapasowej z Unicode na UTF8, otwierając go w Notatniku i przechodząc do Plik -> Zapisz jako. Zmień listę rozwijaną Kodowanie z Unicode na UTF8. (Zmień także Zapisz jako typ z Dokumenty tekstowe (.txt) na Wszystkie pliki, aby uniknąć dodawania rozszerzenia .txt do nazwy pliku kopii zapasowej). Teraz powinno być możliwe przywrócenie kopii zapasowej.

Hehe
źródło
0

Jest również bardzo możliwe z tym błędem, że pole jest zaszyfrowane na miejscu. Upewnij się, że patrzysz na odpowiednią tabelę, w niektórych przypadkach administratorzy utworzą niezaszyfrowany widok, którego możesz użyć zamiast tego. Niedawno spotkałem się z bardzo podobnym problemem.

Josh Barton
źródło
0

Otrzymałem ten sam błąd, gdy próbowałem skopiować plik csv wygenerowany przez program Excel do tabeli Postgres (wszystko na komputerze Mac). Oto jak to rozwiązałem:

1) Otwórz plik w Atom (IDE, którego używam)

2) Wprowadź nieznaczną zmianę w pliku. Zapisz plik. Cofnij zmianę. Zapisz ponownie.

Presto! Polecenie kopiowania działało teraz.

(Myślę, że Atom zapisał go w formacie, który działał)

Anupam
źródło
0

Otwórz plik CSV przez Notepad ++. Wybierz menu Encoding\ Encoding in UTF-8, a następnie napraw ręcznie kilka komórek.

Następnie spróbuj ponownie zaimportować.

Do Nhu Vy
źródło
0

Jeśli twój plik CSV ma zostać wyeksportowany z SQL Server, jest ogromny i zawiera znaki Unicode, możesz go wyeksportować, ustawiając kodowanie jako UTF-8:

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

Na następnej stronie zapyta, czy chcesz skopiować dane z tabeli, czy chcesz napisać zapytanie. Jeśli masz charlub varchartypy danych w tabeli, wybierz opcję zapytania i rzutuj te kolumny jako nvarchar(max). Np. Jeśli myTablema dwie kolumny, gdzie pierwsza jest, varchara druga int, rzutuję pierwszą na nvarchar:

select cast (col1 as nvarchar(max)) col1
       , col2
from myTable
LoMaPh
źródło