Проблема кодирования Python (Юникод) - PullRequest
1 голос
/ 15 июля 2011

Прежде чем бросать помидоры, позвольте мне объяснить мою проблему (я сначала прочитал документацию по Python Unicode).

Я использую модуль json для разбора результата в формате json в словари. Это дает мне строки в кодировке Unicode (например: u "Моя строка t \ xf4t"). Затем я использую Mysqldb для хранения этой строки в моей базе данных Mysql. Я уточнил, что эти базы данных настроены для utf8.

Затем я извлекаю свою запись Mysql, все еще используя MysqlDB. Теперь мой напечатанный результат выглядит как «Моя строка t \ xf4t» (без u). Поскольку мне нужно сравнить вставленную и извлеченную строки, я должен сказать python, что моя извлекаемая строка не закодирована.

Независимо от того, что я пытаюсь, у меня есть UnicodeDecodeError. Я попытался поиграть с кодировкой: unicode (storeInDB, "utf_8") и параметром error ("replace"). Но у меня все еще есть исключения.

У вас есть подсказки?

Спасибо за вашу помощь!

Ответы [ 3 ]

1 голос
/ 15 июля 2011

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

1 голос
/ 16 июля 2011

Скорее всего, вам нужно добавить charset='utf8' к вашему вызову MySQLdb.connect().

Для самого MySQL наборы символов задаются раздельно во многих различных контекстах, в частности, для хранения обеих таблиц.и для соединений (и, к сожалению, во многих случаях MySQL, по-прежнему, по умолчанию использует latin-1).Итак, вы можете, например, перейти к задаче настройки всей базы данных для использования UTF-8:

CREATE DATABASE somedatabase DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;

И все же, когда вы подключаете клиента, MySQL может все еще думать, что вы общаетесь сэто в какой-то другой кодировке:

mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

Основным решением для этого является выполнение SET NAMES UTF8 сразу после подключения, прежде чем делать что-либо еще:

mysql> SET NAMES UTF8;
mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

Однако в вашем случаеэтого по-прежнему недостаточно, потому что сам модуль MySQLdb python также хочет быть полезным и автоматически кодировать / декодировать нативные строки Python для вас.Итак, вы должны установить набор символов в MySQLdb.Это лучше всего сделать, как упоминалось ранее, передавая charset='utf8' при создании соединения MySQLdb.(Это также приведет к тому, что MySQLdb сообщит серверу mysql, что ваше соединение использует UTF8, поэтому вам не нужно запускать SET NAMES UTF8 напрямую)

1 голос
/ 15 июля 2011

u"My string t\xf4t" - это строка Unicode (ее тип unicode), но "My string t\xf4t" - строка байтов (ее тип str).

unicode(storedInDB, "utf_8") пытается декодировать строку байтов как UTF-8, но "My string t\xf4t" не является допустимым UTF-8.

...