Как решить ошибки копирования последовательности UTF8.
-
16-10-2019 - |
Вопрос
Мне дали задачу перенести базу данных PostgreSQL 8.2.x на другой сервер. Для этого я использую PGADMIN 1.12.2 (на Ubuntu 11.04, кстати) и используя резервное копирование и восстановление, используя пользовательский/сжатый формат (.backup) и кодирование UTF8.
Оригинальная база данных находится в UTF8, как SO:
-- Database: favela
-- DROP DATABASE favela;
CREATE DATABASE favela
WITH OWNER = favela
ENCODING = 'UTF8'
TABLESPACE = favela
CONNECTION LIMIT = -1;
Я создаю эту базу данных точно такой же на сервере назначения. Но когда я восстанавливаю базу данных из файла .backup, используя опцию восстановления, это дает мне некоторые из этих ошибок:
pg_restore: restoring data for table "arena"
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2173; 0 35500 TABLE DATA arena favela
pg_restore: [archiver (db)] COPY failed: ERROR: invalid byte sequence for encoding "UTF8": 0xe3a709
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".
CONTEXT: COPY arena, line 62
Когда я проверяю, какая запись запустила эту ошибку на фактических условиях, в некоторых полях Vartext есть диаклитические символы, такие как ç (используется на португальском языке, например, «CaCa»), и когда я вручную удаляю их из текста в записях, ошибка передает к следующей записи. У них есть - с тех пор, как копия имеет ошибку, она перестает вставлять данные в эту таблицу. И я не хочу заменять их вручную один за другим, чтобы сделать это.
Но это довольно странно, потому что с UTF8 не должно быть такого рода проблем, верно?
Я не знаю, как они туда попали в первую очередь. Я только мигрирую в базу данных, и я как -то почитаю, что каким -то образом база данных была похожа на Latin1, а затем была неправильно изменена на UTF8.
Есть ли способ проверить, имеет ли таблица/база данных недействительные последовательности UTF8? Или какой -либо способ обеспечить соблюдение/разведку этих символов в UFT8, чтобы я не сталкивался с какими -либо проблемами, когда я выполняю восстановление?
Заранее спасибо.
Решение
Копая в Интернете, я видел, что это довольно распространенная проблема. Общее решение состоит в том, чтобы использовать дамп формата простого текста и подавать его через ICONV, чтобы исправить кодирование.
Здесь больше информации об этом.
Другие советы
"Я не знаю, как они туда попали в первую очередь"
Это могло произойти, как описано здесь - Хотя это генерирует ошибку на 8.4:
Если вы создаете таблицу с любым типом текста (т. Е. Текст, Varchar (10) и т. Д.), То вы можете вставить неверную байтовую последовательность в это поле, используя восьмидесные побеги.
Например, если у вас есть база данных, кодируемая UTF8, вы можете сделать:
=> Создать таблицу foo (t text);
=> Вставить в значения foo (e ' 377');
Теперь, если вы скопируете таблицу, вы не можете скопировать полученный файл обратно. Это означает, что ваши резервные копии PG_DUMP не смогут восстановить. Единственный способ вернуть ваши данные-это повторно разместить эту ценность.
Есть хороший пост в этом Отличный блог об общих проблемах и некоторых способах справиться с ними
Это, вероятно, с кодированием по умолчанию, используемой в вашей среде Unix/Linux. Чтобы проверить, какая кодировка в настоящее время является по умолчанию, выполните следующее:
$ echo $LANG
en_US
В этом случае мы можем ясно видеть, что это не является кодированием UTF-8, на которую опирается команда копирования.
Итак, чтобы исправить это, мы просто установили переменную LANG в примере на следующее:
$ export LANG=en_US.UTF-8
Примечание. Это будет доступно только для текущего сеанса. Добавьте его в ~/.bashrc или аналогично, чтобы он был доступен для запуска любого будущего сеанса оболочки.
Я не рекомендую слепо запускать ICONV на дамп простого текста, потому что он может преобразовать допустимые символы (например, китайские иероглифы) в некоторые другие символы. Лучше найти неверный символ UTF8, выполняя команду ниже.
grep -naxv '.*' plain_text_dump.sql
а затем запустите ICONV на конкретных данных. Проверять этот документ для подробного пошагового объяснения.