Вы перепутались с кодировкой. Вот пример того, как вы это сделали:
Исходный символ, вероятно, был не апострофом, а либо ‘
(символ ЮНИКОД 2018), либо ’
(символ ЮНИКОД 2019).
Исходный файл, вероятно, был закодирован в UTF-8, где символ закодирован как Hex E2 80 98 (для U + 2018) или Hex E2 80 99 (для U + 2019).
Теперь вы использовали COPY
(вероятно, COPY FROM STDIN
, вы не сообщаете нам подробности) с другой однобайтовой кодировкой, например LATIN1
(ISO 8859-1). Затем PostgreSQL будет интерпретировать каждый байт как один символ и преобразовать его в кодировку базы данных (UTF8
).
Первый байт (шестнадцатеричный E2, â
в LATIN1
) станет шестнадцатеричным C3 A2 в UTF-8, а второй байт (Hex 80, непечатаемый управляющий символ в LATIN1
) станет Hex C2 80 в UTF-8, и это именно то, что вы наблюдаете.
Вы можете проверить мой гипотеза путем проверки двух следующих байтов: Hex C2 98 или Hex C2 99.
Решение состоит в том, чтобы правильно указать кодировку файла как UTF-8 при загрузке файла CSV в базу данных. С COPY
вы можете использовать опцию ENCODING
, чтобы сделать это.