gpt4 book ai didi

python - sqlalchemy connection.execute() 上的 UnicodeDecodeError 用于选择查询

转载 作者:行者123 更新时间:2023-12-04 14:57:25 25 4
gpt4 key购买 nike

我正在使用 sqlalchemy 核心来执行基于字符串的查询。我已将连接字符串上的字符集设置为 utf8mb4,如下所示:

"mysql+mysqldb://{user}:{password}@{host}:{port}/{db}?charset=utf8mb4"

对于一些简单的选择查询(例如,select name from users where id=XXX limit 1),当结果集有一些 unicode 字符(例如,'ì 等),它会出现以下错误:

UnicodeDecodeError:“utf-8”编解码器无法解码位置 11 中的字节 0x9a:起始字节无效

但是错误本身是不可重现的。当我从 python shell 运行相同的查询时,它可以正常工作。但它会在网络请求或后台作业中出错。

我正在使用 Python 3.8 和 sqlalchemy 1.3.24。

我还尝试过使用 create_engine()charset: utf8mb4 明确指定为 connect_args 属性。

底层数据库是 mysql 5.7,所有 unicode 列都有 utf8mb4 明确设置为模式中的字符集。更新:数据库实际上是AWS RDS Aurora MySQL。

感谢对错误或如何可靠地重现错误的任何见解。

最佳答案

MySQL 文档 Connect-Time Error Handling描述了当您使用 MySQL 8.0 客户端库连接到具有 utf8mb4 字符集的 MySQL 5.7 服务器时 MySQL 8.0 客户端库中的错误。 MySQL 8.0 客户端请求 utf8mb4_0900_ai_ci 排序规则,但 MySQL 5.7 服务器无法识别该排序规则,因此服务器静默回退到带有 latin1_swedish_ci 排序规则的 latin1 字符集。随后服务器发送 latin1 结果集,但客户端认为它正在接收 utf8mb4,最终导致 UnicodeDecodeError。作为解决方法,您必须显式地 SET NAMES utf8mb4。我创建了一个问题 mysqlclient#504要求 python 客户端每次都这样做。

要确认连接后字符集不正确,请仔细检查服务器的 character_set_client 值(解释语句的字符集),character_set_connection (语句转换成的字符集)和 character_set_results (结果集作为发送的字符集)。如果它们是 latin1,尽管您尝试使用 utf8mb4 进行连接,则可能已触发此错误。

with con.cursor() as c:
c.execute("show variables like 'character_set_%'")
for row in c:
print(row)
(b'character_set_client', b'latin1')
(b'character_set_connection', b'latin1')
(b'character_set_database', b'latin1')
(b'character_set_filesystem', b'binary')
(b'character_set_results', b'latin1')
(b'character_set_server', b'latin1')
(b'character_set_system', b'utf8')
(b'character_sets_dir', b'/usr/share/mysql/charsets/')

我认为该问题的解决方法是在连接后执行以下操作:

# explicitly set connection charset to the same as MySQLdb.connect()
con.query("SET NAMES utf8mb4")
con.store_result()

关于python - sqlalchemy connection.execute() 上的 UnicodeDecodeError 用于选择查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67680277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com