【问题标题】:UnicodeDecodeError on sqlalchemy connection.execute() for select queriessqlalchemy connection.execute() 上的 UnicodeDecodeError 用于选择查询
【发布时间】:2021-08-13 05:50:21
【问题描述】:

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

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

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

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9a in position 11: invalid start byte

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

我正在使用 Python 3.8 和 sqlalchemy 1.3.24。

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

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

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

【问题讨论】:

    标签: python mysql sqlalchemy python-unicode


    【解决方案1】:

    当您使用 MySQL 8.0 客户端库连接到具有 utf8mb4 字符集的 MySQL 5.7 服务器时,MySQL 文档 Connect-Time Error Handling 描述了 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(结果集作为发送的字符集)。如果尽管您尝试使用 utf8mb4 进行连接,但它们是 latin1,则可能已触发此错误。

    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()
    

    【讨论】:

      【解决方案2】:

      你可以在url中使用use_unicode=true参数吗?

      【讨论】:

        猜你喜欢
        • 2012-06-28
        • 2021-05-06
        • 2019-06-07
        • 1970-01-01
        • 2012-08-11
        • 2013-10-19
        • 2011-10-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多