Я сталкиваюсь с проблемой кодировки символов при извлечении данных из более старой базы данных, которая использует кодировку latin1
. Проблема возникает, когда я пытаюсь извлечь из базы данных символы, попадающие в диапазон от \x80
до \x9f
, который отличается от MySQL latin1
(он же windows-1252
в Python) и официального latin1
(ISO-8859-1).
Это стек, который я использую:
- Сервер баз данных MySQL версии 5.1 с кодированием
latin1
на уровне столбцов и сопоставлением latin1-swedish-ci
на уровне таблиц. - Django версии 2.2 с использованием Python3 и mysqlclient версии 1.4.4.
В качестве примера я пытаюсь извлечь слово «нет» из базы данных, где находится апострофзакодировано как \x92
.
Если я не передам кодировку соединению mysqlclient через настройки Django, я получаю сообщение об ошибке «Кодек utf-8 не может декодировать байт 0x92 в позиции 5: недействительноначальный байт ".
Если я передаю latin1 в качестве кодека для соединения, ошибки не возникает, но слово отображается на странице как" Is t ", с пробелом, где должен быть апостроф.
Когда я открываю отдельную сессию оболочки Python и пытаюсь установить соединение из командной строки python, в результате получается «Isn \ x92t».
>>> import MySQLdb
>>> conex = MySQLdb.connect(host=<host>,db=<db>, user=<user>, passwd=<passwd>, charset="latin1")
>>> cursor = conex.cursor()
>>> cursor.execute("select <field> from <table> where id=<id>")
1L
>>> cursor.fetchall()
((u'Isn\x92t',),)
Кажется, что нет никакой разницы, еслиЯ включаю кодировку или нет при совершении звонкаом командной строки. Таким образом, эта строка подключения
>>> conex = MySQLdb.connect(host=<host>,db=<db>, user=<user>, passwd=<passwd>, charset="latin1")
и строка подключения
>>> conex = MySQLdb.connect(host=<host>,db=<db>, user=<user>, passwd=<passwd>)
имеют одинаковый результат.
Есть ли способ установить параметры для строки подключения mysql, которыебудет правильно обрабатывать коды windows-1252? Буду признателен за любую помощь.
========= Редактировать с дополнительной информацией =========
Спасибо за ваш ответ Рик Джеймс. Исходный текстовый фрагмент исчез, но я нашел еще один похожий фрагмент, на котором он не работает: женский.
Вот выбор HEX:
mysql> SELECT title, HEX(title) from <table> where id = <id>
| title | HEX(title)
| Women?s | 576F6D656E9273
Я не уверен, что чувствую себя комфортно, помещаяВся инструкция по созданию таблицы в Интернете, но вот что я понял, это важные биты SHOW CREATE TABLE
. Дайте мне знать, если вы ищете что-то еще.
CREATE TABLE `tbl` (
`title` varchar(255) DEFAULT NULL,
) ENGINE=MyISAM AUTO_INCREMENT=9460 DEFAULT CHARSET=latin1
И, наконец, результаты SHOW VARIABLES LIKE 'char%';
:
+--------------------------+----------------------------+
| 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/ |
Изменение кодировки в файле настроек базы данных Django на utf8mb4
В результате возникла та же ошибка Unicode, что и при установке utf8
.
'OPTIONS': {
'charset': 'utf8mb4',
'use_unicode': True,
}
Я все еще немного озадачен тем, почему прямой запрос с использованием автономной среды Python с mysqlclient
не будет работать. Это, по крайней мере, исключило бы любую проблему с Джанго из уравнения.