【问题标题】:aiohttp+sqlalchemy: Can't reconnect until invalid transaction is rolled backaiohttp+sqlalchemy:在回滚无效事务之前无法重新连接
【发布时间】:2017-04-26 11:30:31
【问题描述】:

我正在使用aiohttpsqlalchemy,并且我创建了一个单例,它可以帮助我在需要 SQLAlchemy 实例时进行连接(代码如下)。 不幸的是,每隔一段时间我就会收到以下错误(我通过重新启动服务器来“解决”):

Dec 11 09:35:29 ip-xxx-xxx-xxx-xxx gunicorn[16513]: sqlalchemy.exc.StatementError: (sqlalchemy.exc.InvalidRequestError) 直到无效事务回滚后才能重新连接 [SQL: '... \nFROM ...\nWHERE ... = %(username_1)s \n LIMIT %(param_1)s'] [参数:[{}]]```

有没有办法修复当前的代码? 谢谢:)

CONNECTION_DETAILS = {
    'driver': 'pymysql',
    'dialect': 'mysql',
    'host': os.environ.get('HOST'),
    'port': 3306,
    'user': 'master',
    'password': os.environ.get('PASSWORD'),
    'database': 'ourdb',
    'charset': 'utf8'
}

_instance = None

def __new__(cls, *args, **kwargs):
    if not cls._instance:
        con_str = '{dialect}+{driver}://{user}:{password}@' \
                  '{host}:{port}/{database}?charset={charset}'\
            .format(**cls.CONNECTION_DETAILS)
        try:
            engine = sqlalchemy.create_engine(con_str)

            Session = scoped_session(sessionmaker(bind=engine))
            session = Session()  # Create the ORM handle
        except sqlalchemy.exc.OperationalError:
            logger.exception('Establishing database connection error.')

        cls._instance = super().__new__(cls)
        logger.debug("Returning database's session.")
        cls._instance.session = session

        # Initializing tables
        cls._instance.Users = Users
        cls._instance.Services = Services
        cls._instance.APIKeys = APIKeys

    return cls._instance

【问题讨论】:

  • 我对您的问题一无所知,但是您为什么将 aiohttp 与 sqlalchemy 一起使用?带有异步框架的非异步 orm?
  • 我想这是由于多个 aiohttp 请求在同一个线程中运行,因此由于scoped_sessionscopefunc 在多个任务之间共享Session。见this question

标签: python python-3.x sqlalchemy pymysql aiohttp


【解决方案1】:

这将是一个相当晚的答案。这就是发生的情况:在使用会话时,会引发 sqlalchemy 错误(当用作纯 SQL 时也会引发错误的任何事情:语法错误、唯一约束、键冲突等)。

您必须找到此错误,将其包装到try/except-block 中并执行session.rollback()

之后,您可以恢复会话。

【讨论】:

  • 我在使用 SQLAlchemy 和 MS SQL Server 时遇到了这个问题。在空的 Jupyter 单元中运行 session.rollback() 修复了一些问题。
  • @knitti 这不是暗示需要在每个可能的 CRUD 操作上添加 session.rollback ,然后导致它们抛出相同的错误吗?
【解决方案2】:

从一个 flask_sqlalchemy 用例中得到。解决方法是只运行一次db.session.rollback() 并清除。类似于执行回滚的公认答案

【讨论】:

  • 你在哪里称呼它?
猜你喜欢
  • 2020-02-11
  • 2014-11-29
  • 2015-09-16
  • 2021-02-06
  • 2021-03-06
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 2018-02-09
相关资源
最近更新 更多