Skip to content

fix: drop legacy documents_fts table if exists#7706

Merged
Soulter merged 2 commits intoAstrBotDevs:masterfrom
Sisyphbaous-DT-Project:master
Apr 21, 2026
Merged

fix: drop legacy documents_fts table if exists#7706
Soulter merged 2 commits intoAstrBotDevs:masterfrom
Sisyphbaous-DT-Project:master

Conversation

@Sisyphbaous-DT-Project
Copy link
Copy Markdown
Contributor

@Sisyphbaous-DT-Project Sisyphbaous-DT-Project commented Apr 21, 2026

概要

这个 PR 修复了 AstrBot v4.23.2 引入的一个 SQLite FTS5 兼容性问题。

当用户本地数据库中已经存在一个普通表 documents_fts 时,执行:

CREATE VIRTUAL TABLE IF NOT EXISTS documents_fts USING fts5(...)

SQLite 不会报错,但也不会把这个普通表替换成 FTS5 虚表。随后 AstrBot 会误认为 FTS5 已可用,并在后续写入时触发错误:

sqlite3.OperationalError: table documents_fts has no column named search_text

问题根因

DocumentStorage._initialize_fts5() 之前只尝试创建 FTS 表,但没有校验当前已有的 documents_fts 是否真的是一个合法的 FTS5 虚表,也没有确认它是否包含预期的 search_text 字段。

这会导致以下问题场景:

  1. 用户升级到 v4.23.2
  2. 本地数据库中已存在一个同名普通表 documents_fts
  3. AstrBot 执行 CREATE VIRTUAL TABLE IF NOT EXISTS ... 时被 SQLite 静默跳过
  4. AstrBot 仍将 fts5_available 标记为 True
  5. 后续插入 search_text 时直接报错

变更内容

本 PR 做了以下修复:

  • 抽取 FTS5 表创建逻辑到独立方法
  • 在初始化后增加表结构校验
  • 检测 documents_fts 是否为合法的 FTS5 虚表
  • 检测该表是否包含预期字段 search_text
  • 如果发现是旧的普通表或结构不合法,则自动删除并重建为正确的 FTS5 表
  • 根据实际表定义判断 contentless_delete 是否可用,而不是仅根据创建路径推断
  • 补充回归测试,覆盖“已有同名普通表”的用户升级场景

测试

已验证以下检查通过:

  • python -m ruff check astrbot/core/db/vec_db/faiss_impl/document_storage.py tests/unit/test_document_storage_fts.py
  • python -m pytest tests/unit/test_document_storage_fts.py tests/unit/test_sparse_retriever.py

另外,新增的回归测试覆盖了以下场景:

  • 预先创建普通表 documents_fts
  • 初始化 DocumentStorage
  • 验证可以自动恢复为合法 FTS5 表
  • 验证后续插入与检索流程正常

说明

这个问题是在下游插件用户升级到 AstrBot v4.23.2 后暴露出来的。根本原因不在插件本身,而在 AstrBot 核心对旧 SQLite 状态的兼容处理不完整。

这个修复的目标是让 AstrBot 在面对历史遗留数据库结构时,能够自动识别并恢复到正确的 FTS5 状态,避免用户在升级后因本地数据库残留结构而直接报错。

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend labels Apr 21, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the FTS5 initialization in document_storage.py by adding helper methods for table creation and inspection, including logic to recreate incompatible legacy tables. A new unit test verifies recovery from non-FTS tables. A suggestion was made to improve the robustness of the table inspection logic by normalizing whitespace when checking for the contentless_delete parameter.

Comment thread astrbot/core/db/vec_db/faiss_impl/document_storage.py Outdated
@Sisyphbaous-DT-Project Sisyphbaous-DT-Project changed the title fix: recover FTS5 index from legacy documents_fts table fix: 修复 documents_fts 旧表导致的 FTS5 初始化失败问题 Apr 21, 2026
@Soulter
Copy link
Copy Markdown
Member

Soulter commented Apr 21, 2026

本地数据库中已存在一个同名普通表 documents_fts

这个是用户自行创建的表?

@Sisyphbaous-DT-Project
Copy link
Copy Markdown
Contributor Author

本地数据库中已存在一个同名普通表 documents_fts

这个是用户自行创建的表?

不是说一定是用户手动创建的
目前能确认的是:升级到 v4.23.2 时,本地 SQLite 中已经存在一个同名的普通表 documents_fts,而当前初始化逻辑只做 CREATE VIRTUAL TABLE IF NOT EXISTS,不会校验这个已有表是否真的是 FTS5 虚表,所以后续会误判为可用并在写入 search_text 时失败
这个普通表的来源可能是历史遗留库、外部脚本/插件写入,就比如livingmemory的记忆总结就有概率导致这个问题出现;我的修复并不依赖它的具体来源,而是对“已有同名但结构不兼容”的状态做自动恢复

@Sisyphbaous-DT-Project
Copy link
Copy Markdown
Contributor Author

就比如livingmemory的记忆总结就有概率导致这个问题出现

不过这个问题是在livingmemory场景下暴露出来的,但我目前不能严格保证那个普通表就是livingmemory创建的

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Apr 21, 2026
@Soulter Soulter changed the title fix: 修复 documents_fts 旧表导致的 FTS5 初始化失败问题 fix: drop legacy documents_fts table if exists Apr 21, 2026
@Soulter Soulter merged commit d9ab353 into AstrBotDevs:master Apr 21, 2026
21 checks passed
Soulter pushed a commit that referenced this pull request Apr 22, 2026
* fix: recover FTS5 index from legacy documents_fts table

* fix: normalize SQL whitespace when checking contentless_delete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants