【发布时间】:2020-07-22 19:02:44
【问题描述】:
查询:
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 没有得到相同的处理,我最终得到? 而不是'
【问题讨论】:
-
(1) “花式”撇号
’(右单引号,U+2019)不是 Latin-1 的一部分。升级到 UTF-8 绝对是最好的选择。现在是 2020 年,UTF-8 无处不在。 (2)value.encode('utf8', 'ignore').decode('utf8')有效果的情况非常少见。排版引号都不是。 99.9% 的情况下,此表达式返回原始的value不变。 -
@lenz - UTF-8 会更好。但是,评论不正确。 Hex 92 是“右单引号”的 latin1 编码。
-
@RickJames 这取决于您如何定义“Latin-1”。代码点 0x92 是标准 Latin-1 (ISO-8859-1) 中的控制字符。它是 Windows 代码页 1252(以及其他)中的一个引号,它是对前者的修改,通俗地称为“Windows Latin 1”。我不知道 MySQL 如何定义“Latin-1”;如果是后者,我不会感到惊讶。
-
@lenz - 我认为 MySQL 的 latin1 没有做任何事情来验证它接收到的字节。另一方面,Utf8 对几乎任何具有 8 位字符的 latin1 字符串(包括所讨论的 92 位)都发出尖叫声。
-
@RickJames 这也是真的。除非您知道解释后的字符串应该是什么样子,否则没有验证任何 8 位编码的好方法。
标签: python mysql utf-8 ascii latin