RFC: Replace Peewee with SQLModel

在 RAGFlow 项目 Python 后端的开发/维护过程中,团队发现基于 Peewee 的 ORM 架构在以下场景中频繁触发连接问题:批量插入时会嵌套 @DB.connection_context() 装饰器(覆盖 api/db/services/ 下约 215 处调用点);手动调用的 db.c

RFC: Replace Peewee with SQLModel

RFC: Replace Peewee with SQLModel

快速结论:该 Issue 是 RAGFlow 社区提出的 ORM 替换 RFC(PeeweeSQLModel),并非已复现的 Bug。问题背景反映了 Peewee 在连接管理、嵌套上下文冲突和丢失连接恢复上的固有缺陷,但方案仍处于 Draft / PR 阶段。如果希望参与迁移或评估影响,优先查看两个基础 PR(#14776、#14777)以及项目后续计划的 Go 版本重构进度。

问题场景

在 RAGFlow 项目 Python 后端的开发/维护过程中,团队发现基于 Peewee 的 ORM 架构在以下场景中频繁触发连接问题:批量插入时会嵌套 @DB.connection_context() 装饰器(覆盖 api/db/services/ 下约 215 处调用点);手动调用的 db.connect() / db.close() 存在于 agent_api.py 和 apps/__init__.py 中;MySQL 错误码 2013/2006 导致 InterfaceError: (0, '') 或连接泄漏。

报错原文

InterfaceError: (0, '')
Lost connection to MySQL server during query  (error: 2013)
MySQL server has gone away  (error: 2006)

原因分析

根本原因来自 Peewee 自身的短板,并非特定版本的 Bug:

  • 嵌套连接上下文冲突@DB.connection_context() 是“扁平”(flat) 装饰器,不能在嵌套调用中明智地跟踪引用计数,导致子层误打开或错误返回连接,触发 InterfaceError
  • 手动连接管理散乱:agent_api.py 中 test_db_connection 手动 open/close,apps/__init__.py 全局异常处理器中也会关闭连接,缺乏统一协议。
  • Peewee 内置连接池无法可靠恢复连接:项目不得不自己实现 RetryingPooledMySQLDatabase(db_models.py:260)来捕获 OperationalError, InterfaceError 并重试。
  • 会话生命周期不明确:没有统一的“请求-连接”管理主体,长时间任务和并发请求的连接释放难以控制。

环境排查

  • ORM/依赖:Peewee(当前使用)、SQLAlchemy 2.0(迁移目标底层)、SQLModel(统一数据模型)、Alembic(数据库迁移脚手架)
  • Python 版本:未在 Issue 中指定,建议参考项目 pyproject.toml
  • 数据库:MySQL(错误码 2013/2006 提示连接丢失)
  • 框架:FastAPI(SQLModel 作者与 FastAPI 作者相同)

解决步骤

按 Issue 讨论和 PR 进展,以下是社区规划的迁移路径:

  1. 审查并合入基础设施 PR:检查 PR #14776(SQLAlchemy 2.0 引擎、scoped_session、Alembic 脚手架、pyproject.toml 依赖)和 PR #14777(修复 test_db_connection 连接泄漏)。目前 Peewee 代码不被触及。
  2. 生成 Alembic 基线迁移:从当前数据库实时 Schema 生成第一个 Alembic 迁移文件。
  3. 增量转换服务层:将 api/db/services/ 下约 215 处 @DB.connection_context() 逐步替换为 SQLModel / SQLAlchemy 会话管理。
  4. 协调冲突分支:Issuer 在评论中明确表示“Phase 3 会与大多数开放功能分支发生冲突”,建议开始前确认当前活跃开发方向。
  5. (注意:作者在评论末尾透露 RAGFlow 项目“nearly done porting … from python to go”,Python 端即将消亡。因此直接参与 SQLModel 迁移可能不是社区当前首要目标,建议同步评估 Go 版本进度。)

验证方法

该 Issue 是 RFC(Request for Comments),并非 Bug,没有标准验证方法。如果按 PR 步骤合并后,可通过以下方式确认环境是否正常:

  • 运行现有单元测试(特别是 api/db/services/ 下的连接相关测试)
  • 启动 RAGFlow 应用并模拟多层嵌套 connection_context 的业务流程(如批量插入 + 子服务调用),观察是否有 InterfaceError 复现
  • 检查 MySQL 的错误日志,确认不再出现 2013/2006 断开错误

参考来源

infiniflow/ragflow #14750

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 12561

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注