Кодировка и декодирование символов в Python с MySQL - PullRequest
0 голосов
/ 10 апреля 2020

Для запроса:

SHOW VARIABLES LIKE 'char%';

MySQL База данных возвращает:

character_set_client    latin1
character_set_connection    latin1
character_set_database  latin1
character_set_filesystem    binary
character_set_results   latin1
character_set_server    latin1
character_set_system    utf8
character_sets_dir  /usr/local/mysql-5.7.27-macos10.14-x86_64/share/charsets/

В моем сценарии Python:

conn = get_database_connection()
conn.setdecoding(pyodbc.SQL_CHAR, encoding='latin1')
conn.setdecoding(pyodbc.SQL_WCHAR, encoding='latin1')

Для одного из столбцы со следующим значением:

N’a pas

Python возвращает:

N?a pas

Между N и a имеется знак вопроса в форме звезды. Как я могу прочитать это как есть? Какой лучший способ справиться с этим? Я читал о преобразовании моей базы данных в utf-8, но это похоже на длинный выстрел с хорошим шансом сломать другие вещи. Есть ли более эффективный способ сделать это?

В некоторых местах кода я сделал:

value = value.encode('utf-8', 'ignore').decode('utf-8')

для обработки utf-8 данных, таких как акцентированные символы, но apostrophe не был обработан с тем же, и я закончил с ? вместо '

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Преобразование базы данных в UTF-8 лучше в долгосрочной перспективе, но рискованно, потому что вы можете нарушить другие вещи, как вы говорите. Вы можете изменить кодировку базы данных connection на UTF-8. Таким образом, вы получаете строки в кодировке UTF-8 из базы данных, не меняя способ хранения данных.

conn.setdecoding(pyodbc.SQL_CHAR, encoding='utf8')
conn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf8')

Если это кажется слишком рискованным, но вы можете рассмотреть возможность использования двух отдельных соединений с базой данных, оригинал и один в utf8, и постепенно перенесите приложение на использование utf8, так как у вас есть время для тестирования.

Если даже это кажется слишком рискованным, возможно, попробуйте использовать более похожую кодировку символов до mysql версии латыни1. MySQL 'latin1' на самом деле является расширенной версией cp1252 кодировки , которая сама является расширением Microsoft для "стандартного latin1", который используется в Python (среди прочих).

conn.setdecoding(pyodbc.SQL_CHAR, encoding='cp1252')
conn.setdecoding(pyodbc.SQL_WCHAR, encoding='cp1252')
1 голос
/ 11 апреля 2020

Не используйте любую форму кодирования / декодирования; это только усложняет ваш код и скрывает больше ошибок. Фактически, вы можете пытаться «сделать два неправильных, сделать правильное».

Go с utf8 (или utf8mb4).

Примечания к «вопросительному знаку»: Проблема с UTF-8 символами; то, что я вижу, не то, что я хранил
Примечания Python: http://mysql.rjweb.org/doc.php/charcoll#python

...