【问题标题】:Sqlalchemy "Packet sequence number wrong" despite using scoped_session尽管使用了 scoped_session,但 Sqlalchemy “数据包序列号错误”
【发布时间】:2020-11-23 09:34:16
【问题描述】:

我将 Flask 与 Sqlalchemy 一起使用,并且由于从 mysqldb 切换到 pymysql,我收到此错误: InternalError('(pymysql.err.InternalError) Packet sequence number wrong - got 29 expected 1')(数字因查询而异)

这个错误非常罕见(大约 100 分之一),我从 mysqldb 切换到 pymysql 的原因是因为 mysqldb 一直以类似的速度创建 utf8 解码错误。是否有可能我仍然因此而出错,并且 pymysql 正在将“无效的起始字节”解释为“无效的数据包序列”错误,来自下游的同一个问题?

正如标题所说,我已经实现了 scoped_session 并没有解决问题。也许我做错了什么?

engine_creation.py

def create_engine(db="")
    engine = sqlalchemy_package.create_engine(
        'mysql+pymysql://' + acc + ':' + pw + '@'
        + host + ':' + port + '/' + db + '?charset=utf8mb4',
        pool_recycle=3600, pool_size=25, max_overflow=5)

query_execution.py

from sqlalchemy.orm import scoped_session, sessionmaker
session_factory = sessionmaker(autocommit=True)
def execute_query(engine, query, parameters=None):
    session_factory.configure(bind=engine)
    my_session = scoped_session(session_factory)
    result = my_session.execute(query, parameters)  # noqa
    return result

some_resource.py

from engine_creation import create_engine
from query_execution import execute_query
engine = create_engine(db=some_db)
result_proxy = execute_query(engine, query, parameters)

将 +pymysql 更改为 +mysqldb 将完全相同,但“数据包序列”错误将更改为 UnicodeDecodeError('utf-8', b'\xf6', 8, 9, 'invalid start byte') 。有没有人听说过这个?我仍在尝试调试为什么会收到 UnicodeDecodeError,如果切换到不同的方言会产生不同的错误 - 或相同的错误,表达方式不同。

代码在没有 scoped_session 的情况下工作正常,如果它不能修复数据包序列错误,它似乎是多余的。抱歉,这似乎是同时出现多个问题,但我的直觉告诉我这些问题是相关的。

【问题讨论】:

  • 您能否提供一个minimal reproducible example 可以确定地产生错误?
  • 这是所需的最少代码。您只需要选择一个 varchar 字段,例如“interférence”,它会产生 UTF-8 解码错误。正如解释的那样,交换方言将改变错误。不幸的是,这个错误是不一致的,这是问题的一部分。我不能强迫它每次都发生。我将添加一些关于使用的数据库的细节。
  • 虽然这是不可重现的,但如果出现这样的错误,这是最重要的。换句话说,即使我拿了你的 sn-ps,我也不知道如何以某种可能会产生错误的方式运行代码。
  • 我知道并且我预计这将很难重现。这就是为什么我的主要关注点是为什么我得到了“数据包序列错误”,尽管已经正确实现了 scoped_sessions(并询问我是否这样做了)。如果我提供的代码没有错误,则错误应该(或必须)与 utf-8 解码错误有关,被 pymysql 误解。对于将来遇到类似问题的任何人。升级到 MariaDB 10.5 解决了这个问题,显然它是由 MySQL 5.7 引起的。不幸的是,谷歌让我相信这个错误总是由无范围的会话和烧瓶中的线程安全引起的。
  • 关于作用域会话,如果您每次执行时都构建注册表,它不会做太多:)。 Scoped session 是一个注册表,可以更轻松地将会话的生命周期与其他事物(例如线程)的生命周期联系起来。

标签: python flask sqlalchemy


【解决方案1】:

正如预期的那样,此错误与烧瓶、sqlalchemy 或无作用域会话无关。在我看来,这是由 MySQL 5.7 与 pymysql 方言交互引起的错误,它抛出“数据包序列错误”,而实际上它是一个 UTF-8 问题。

无论如何,升级到 MariaDB 10.5 解决了这个问题。没有必要实现 scoped_sessions。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多