上下文:我正在开发一个 Flask 应用程序,在 CherryPy 上运行,DB 使用 SQLAlchemy ORM 处理。
问题:
该应用程序运行良好并且可以执行我想要的所有操作,但是,如果我有一个从 DB 获取一些数据并显示的页面,并且我按住“Ctrl + R”或“F5”。也就是说,不断刷新页面,发出那么多数据库请求。前几个很好,然后就坏了。记录以下错误:
(OperationalError) (2013, 'Lost connection to MySQL server during query')
Can't reconnect until invalid transaction is rolled back (original cause:
InvalidRequestError: Can't reconnect until invalid transaction is rolled back)
This result object does not return rows. It has been closed automatically.
(ProgrammingError) (2014, "Commands out of sync; you can't run this command now")
还有另一个困扰我的错误(但这次没有记录),它是
dictionary changed size during iteration
当我使用获得的值来填充字典来迭代查询时,就会发生这种情况。字典是函数的本地(字典的范围)。
更多信息:
我如何处理会话:
进入任何页面时都会创建一个新会话,使用该会话执行所有数据库事务,并且在呈现 HTML 之前关闭会话。从技术上讲,这意味着会话的范围与 HTTP 请求相同。
只有在表格或表格session.rollback()
中出现异常时,我才会这样做。在任何操作期间不。我很确定我犯了一些愚蠢的错误,或者没有以正确的方式做事。updating
inserting
rollback()
query()
像这样的无限刷新并不是一个可能的场景,但不能被忽视。另外,我认为当有很多用户同时使用它时,行为会相似。
SQLAlchemy 引擎 sessionmaker 的处理方式:
sql_alchemy_engine = create_engine(self.db_string, echo=False, encoding="utf8", convert_unicode=True, pool_recycle=9)
sqla_session = sessionmaker(bind=sql_alchemy_engine)
就像 SQLA 文档中推荐的那样,它只执行一次,并且sqla_session()
在需要时创建并返回一个新会话。