sqlalchemy.exc.PendingRollbackError: This Session‘s transaction has been rolled back due to a previo

报错

File "/home/**/projects/wxb_ai_txt_server/question_db.py", line 57, in get_qid_by_question
    ).all()
      ^^^^^
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/query.py", line 2688, in all
    return self._iter().all()  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/query.py", line 2842, in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
                                                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2262, in execute
    return self._execute_internal(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2123, in _execute_internal
    ) = compile_state_cls.orm_pre_session_exec(
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/context.py", line 551, in orm_pre_session_exec
    session._autoflush()
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2928, in _autoflush
    self.flush()
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 4179, in flush
    self._flush(objects)
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 4271, in _flush
    flush_context.transaction = transaction = self._autobegin_t()._begin()
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "", line 2, in _begin
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/state_changes.py", line 103, in _go
    self._raise_for_prerequisite_state(fn.__name__, current_state)
  File "/home/**/.local/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 912, in _raise_for_prerequisite_state
    raise sa_exc.PendingRollbackError(
sqlalchemy.exc.PendingRollbackError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')
[SQL: INSERT INTO user_question (user_id, question, keywords, qembedding, qid, dbid, create_time, update_time) VALUES (%(user_id)s, %(question)s, %(keywords)s, %(qembedding)s, %(qid)s, %(dbid)s, %(create_time)s, %(update_time)s)]

原因分析

这个错误是由于在尝试执行SQLAlchemy的flush()操作时,由于之前的某个异常导致当前事务被回滚。在这个特定的例子中,原始异常是由于在执行一个INSERT操作时丢失了与MySQL服务器的连接(错误代码2013)。

处理这个问题的方法取决于具体的应用场景和代码逻辑,但以下是一些建议的步骤:

处理方法

检查数据库连接:

确保数据库服务器的稳定性和可访问性。
如果可能,增加数据库连接的超时时间。
考虑使用连接池来管理数据库连接,这有助于在连接丢失时自动恢复。

错误处理和重试逻辑:

在代码中添加适当的错误处理逻辑,以便在发生此类错误时能够捕获异常并执行相应的操作(如重试、记录错误、通知管理员等)。
你可以考虑使用装饰器或上下文管理器来实现重试逻辑。

事务管理:

如果你的操作需要在事务中执行,确保你正确地管理了事务的边界。
在捕获到PendingRollbackError异常后,你可能需要调用Session.rollback()来回滚当前事务,然后根据需要开始一个新的事务。
如果你不打算在同一个事务中继续操作,也可以考虑关闭当前的Session并创建一个新的Session。

优化查询和数据库结构:

如果INSERT操作涉及大量数据或复杂的查询,考虑优化查询或更改数据库结构以提高性能。
使用索引、分区或其他数据库特性来优化数据访问。

查看日志和监控:

检查数据库的日志文件,以获取有关连接丢失原因的更多信息。
使用监控工具来跟踪数据库性能和任何潜在的问题。

更新库和依赖项:

确保你使用的SQLAlchemy和PyMySQL库是最新版本的,因为旧版本可能包含已知的问题或bug。

代码审查和测试:

审查相关的数据库访问代码,确保它符合最佳实践,并且没有逻辑错误或资源泄露。
编写单元测试和集成测试来验证数据库操作的正确性和稳定性。

例子

下面是一个简单的例子,展示了如何在捕获到PendingRollbackError后执行回滚操作:

from sqlalchemy.exc import PendingRollbackError  
from your_app import session  # 假设你已经配置了一个SQLAlchemy session  
  
try:  
    # 你的数据库操作代码  
    result = session.query(...).all()  # 这只是一个示例查询,实际代码可能会有所不同  
    # ... 其他操作 ...  
    session.commit()  # 提交事务  
except PendingRollbackError:  
    session.rollback()  # 回滚事务  
    # 这里可以添加额外的错误处理逻辑,比如记录错误、重试等  
except Exception as e:  # 捕获其他异常  
    session.rollback()  # 回滚事务以防万一  
    # 记录异常信息或执行其他操作

请注意,这个例子中的session应该是你的应用中配置好的SQLAlchemy会话对象。此外,根据你的具体需求,你可能需要对异常处理逻辑进行更详细的定制。

你可能感兴趣的:(后端,python,数据库,python,flask,sqlalchemy)