Неверная последовательность байтов для кодирования "UTF8"

Я пытается импортировать некоторые данные в мою базу данных. Поэтому я создал временную таблицу,

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

И теперь я пытаюсь импортировать данные,

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

Но тогда я получаю ошибку,

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

Как это исправить? Нужно ли мне изменять кодировку всей моей базы данных (если да, как?) Или я могу изменить только кодировку моей таблицы tmp? Или я должен попытаться изменить кодировку файла?

Ответ 1

Если вам нужно хранить данные UTF8 в вашей базе данных, вам нужна база данных, которая принимает UTF8. Вы можете проверить кодировку вашей базы данных в pgAdmin. Просто щелкните правой кнопкой мыши базу данных и выберите "Свойства".

Но эта ошибка, похоже, говорит о том, что в исходном файле есть недопустимые данные UTF8. Это означает, что утилита copy обнаружила или догадалась, что вы передаете ей файл UTF8.

Если вы работаете в каком-либо варианте Unix, вы можете проверить кодировку (более или менее) с помощью file утилиты.

$ file yourfilename
yourfilename: UTF-8 Unicode English text

(Я думаю, что это будет работать на Mac в терминале тоже.) Не уверен, как это сделать под Windows.

Если вы используете ту же самую утилиту для файла, полученного из систем Windows (то есть для файла, не закодированного в UTF8), она, вероятно, будет отображать что-то вроде этого:

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

Если что-то не так, вы можете попытаться преобразовать свои входные данные в известную кодировку, изменить кодировку клиента или и то, и другое. (Мы действительно расширяем границы моих знаний о кодировках.)

Вы можете использовать утилиту iconv для изменения кодировки входных данных.

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

Вы можете изменить кодировку psql (клиента), следуя инструкциям по поддержке набора символов. На этой странице найдите фразу "Включение автоматического преобразования набора символов".

Ответ 2

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

Добавление опции encoding работало в моем случае.

Ответ 3

По-видимому, я могу просто установить кодировку на лету,

 set client_encoding to 'latin1'

И затем повторно запустите запрос. Не уверен, какую кодировку я должен использовать, хотя.


latin1 сделал символы четкими, но большинство акцентированных символов были в верхнем регистре, где их не должно было быть. Я предположил, что это произошло из-за плохого кодирования, но я думаю, что на самом деле данные были просто плохими. Я закончил тем, что сохранил кодировку latin1, но предварительно обработал данные и исправил проблемы с корпусом.

Ответ 4

Если вы в порядке с отбрасыванием неконвертируемых символов, вы можете использовать флаг -c

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

а затем скопируйте их в таблицу

Ответ 5

Эта ошибка означает, что кодировка записей в файле отличается по отношению к соединению. В этом случае iconv может вернуть ошибку, иногда даже несмотря на флаг //IGNORE:

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

iconv: незаконная входная последовательность в позиции (некоторое число)

Трюк заключается в том, чтобы найти неправильные символы и заменить его. Для этого в Linux используйте редактор "vim":

vim (текстовый файл), нажмите кнопку "ESC": и введите ": goto (номер, возвращаемый iconv)"

Чтобы найти символы без ASCII, вы можете использовать следующую команду:

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

Если вы удалите неверные символы, проверьте, действительно ли вам нужно преобразовать ваш файл: возможно, проблема уже решена.

Ответ 6

Это зависит от того, какой тип машины/кодирования сгенерировал ваш файл импорта.

Если вы получаете его из английской или западноевропейской версии Windows, лучше всего установить его на "WIN1252". Если вы получаете его из другого источника, обратитесь к списку кодировок символов здесь:

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

Если вы получаете его с Mac, вам, возможно, придется запустить его с помощью утилиты "iconv", чтобы преобразовать ее из MacRoman в UTF-8.

Ответ 7

Ну, я столкнулся с той же проблемой. И что решило мою проблему:

В excel нажмите "Сохранить как". Из типа сохранения выберите .csv Нажмите Инструменты. Затем выберите веб-параметры из выпадающего списка. В разделе Кодировка сохраните документ как Юникод (UTF-8). Нажмите "ОК". Сохраните файл. Сделано!

Ответ 8

выполните следующие действия для решения этой проблемы в pgadmin:

  • SET client_encoding = 'ISO_8859_5';

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

Ответ 9

У меня была такая же проблема, и я нашел здесь приятное решение: http://blog.e-shell.org/134

Это вызвано несоответствием в ваших кодировках базы данных, конечно, потому что база данных, откуда вы получили дамп SQL, была закодирована как SQL_ASCII, а новая - как UTF8... Recode - это небольшой инструмент из проекта GNU, который позволяет вам изменять "на лету" кодировку данного файла.

Итак, я просто перекодировал файл дампа перед его воспроизведением:

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

В системах Debian или Ubuntu перекодирование может быть установлено через пакет.

Ответ 10

Вы можете заменить символ обратной косой черты, например, символом канала, с sed.

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

Ответ 11

Эта ошибка может возникнуть, если входные данные содержат escape-символ. По умолчанию escape-символ является символом "\", поэтому, если ваш текст ввода содержит символ "\", попробуйте изменить значение по умолчанию с помощью опции ESCAPE.

Ответ 12

Для python вам нужно использовать

Класс pg8000.types.Bytea(str)     Bytea - это str-производный класс, который сопоставляется с массивом байтов PostgreSQL.

или

Pg8000.Binary(значение)    Создайте объект, содержащий двоичные данные.

Ответ 13

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

вы можете попробовать это для обработки кодировки UTF8.

Ответ 14

Краткий пример решения этой проблемы в PHP-

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

Подробная информация об ошибке: Поскольку база данных POSTGRES не обрабатывает другие символы, кроме символов UTF-8, когда мы пытаемся передать указанные выше входные данные в столбец, она выдает ошибку "недопустимая последовательность байтов для кодировки" UTF8 ": 0xab".

Так что просто конвертируйте это значение в UTF-8 перед вставкой в базу данных POSTGRES.

Ответ 15

С этой ошибкой также очень возможно, что поле зашифровано на месте. Убедитесь, что вы смотрите на нужную таблицу, в некоторых случаях администраторы создадут незашифрованное представление, которое вы можете использовать вместо этого. Недавно я столкнулся с очень похожими проблемами.

Ответ 16

У меня такая же ошибка, когда я пытался скопировать CSV, сгенерированный Excel, в таблицу Postgres (все на Mac). Вот как я это решил:

1) Откройте файл в Atom (используемая среда IDE)

2) Сделайте незначительное изменение в файле. Сохраните файл. Отмените изменение. Сохраните снова.

Presto! Теперь команда копирования работает.

(Я думаю, что Atom сохранил его в формате, который работал)

Ответ 17

Откройте файл CSV с помощью Notepad++. Выберите меню Encoding\Encoding in UTF-8, затем вручную исправьте несколько ячеек.

Затем попробуйте импортировать снова.

Ответ 18

Если ваш CSV будет экспортирован из SQL Server и содержит символы Unicode, экспортируйте его, установив кодировку UTF-8:

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

На следующей странице спрашивается, хотите ли вы скопировать данные из таблицы или написать запрос. Если в вашей таблице есть типы данных char или varchar, выберите опцию запроса и приведите эти столбцы как nvarchar(max). Например, если myTable имеет два столбца, первый из которых - varchar, а второй - int, я приведу первый к nvarchar:

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