【发布时间】:2020-02-11 12:18:21
【问题描述】:
从使用latin1 编码的旧数据库中检索数据时,我遇到了字符编码问题。当我尝试从数据库中检索位于\x80 到\x9f 范围内的字符时,就会出现问题,这是 MySQL 的 latin1(在 Python 中又称为 windows-1252)和官方 @ 之间的不同范围。 987654326@ (ISO-8859-1)。
这是我正在使用的堆栈:
- MySQL 数据库服务器版本 5.1,在列级别使用
latin1编码,在表级别使用latin1-swedish-ci排序规则。 - 使用 Python3 的 Django 版本 2.2 和 mysqlclient 版本 1.4.4。
例如,我试图从撇号编码为\x92 的数据库中检索单词“Isn't”。
如果我没有通过 Django 设置将字符集传递给 mysqlclient 连接,则会收到错误消息“'utf-8' codec can't decode byte 0x92 in position 5: invalid start byte”。
如果我将 latin1 作为编解码器传递给连接,则不会出现错误,但该单词会以“Isn t”的形式呈现到页面上,并且撇号应该是空格。
当我打开一个单独的 python shell 会话并尝试从 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 代码?任何帮助将不胜感激。
========= 编辑附加信息 =========
感谢您的回复瑞克·詹姆斯。原始文本 sn-p 消失了,但我发现了另一个类似的失败的文本:Women's。
这是十六进制选择:
mysql> SELECT title, HEX(title) from <table> where id = <id>
| title | HEX(title)
| Women?s | 576F6D656E9273
我不确定将整个 create table 语句放到网上是否合适,但我认为这是 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 会导致与设置为 utf8 时相同的 unicode 错误。
'OPTIONS': {
'charset': 'utf8mb4',
'use_unicode': True,
}
对于为什么使用带有mysqlclient 的独立python 环境的直接查询不起作用,我仍然有点困惑。这至少可以排除任何 Django 问题。
【问题讨论】:
标签: python mysql django python-3.x character-encoding