RAGFlow v0.17.2 → v0.25.6

知识库数据迁移设计方案  ·  2026-06-15  ·  v2.0

目录
  1. 概述与设计原则
  2. 表结构差异分析
  3. 两版本数据库表关系对比
  4. 迁移后 ID 变化矩阵
  5. 用户数据与知识库参数迁移
  6. 迁移架构
  7. Phase 1 — 导出
  8. Phase 2 — 导入
  9. Phase 3 — 核对
  10. 解析内容验证
  11. 权限验证
  12. 配置文件说明
  13. 执行手册
  14. 常见问题与回滚

1. 概述与设计原则

目标

将 RAGFlow v0.17.2 中的知识库、所属用户关系、配置参数及所有文档文件,迁移到 v0.25.6 并重新触发文档解析,最后验证解析结果和权限。

设计原则

🛡️ 安全优先

不直接操作 v0.25.6 数据库。通过 REST API 导入,避免破坏新库结构。

📦 最小依赖

仅需 pymysql + minio + requests。无需安装 RAGFlow 完整依赖。

🔁 可重复

同名 dataset 自动复用,支持增量。失败可重跑,已上传的会跳过。

2. 表结构差异分析

以下对比基于 api/db/db_models.py 中 Peewee ORM 模型定义。v0.17.2 共 28 个模型类,v0.25.6 共 50 个。

2.1 knowledgebase 表

字段v0.17.2v0.25.6变化
tenant_embd_idIntegerField, nullable新增 指向 tenant_llm.id
pipeline_idCharField(32), nullable新增 Agent pipeline ID
graphrag_task_idCharField(32), nullable新增
graphrag_task_finish_atDateTimeField, nullable新增
raptor_task_idCharField(32), nullable新增
raptor_task_finish_atCharField, nullable新增
mindmap_task_idCharField(32), nullable新增
mindmap_task_finish_atCharField, nullable新增
parser_configdefault: {"pages":[[1,1e6]]}default expanded默认值扩展
其余 17 字段无变化

2.2 document 表

字段v0.17.2v0.25.6变化
process_duationFloatFieldprocess_duration重命名
sizeIntegerFieldBigIntegerField类型变更
pipeline_idCharField(32), nullable新增
suffixCharField(32), NOT NULL新增
content_hashCharField(32), nullable新增
meta_fieldsJSONField已移除
parser_configdefault olddefault expanded默认值扩展

2.3 file / file2document / task 表

变化
filesize IntegerField → BigIntegerField 类型变更
file2document无变化
taskprocess_duation 重命名 + 新增 5 列 (task_type/priority/retry_count/digest/chunk_ids) 新增

2.4 Tenant 表差异(关键:影响权限)

v0.25.6 的 Tenant 表新增了 6 个 tenant_xxx_id 整型外键(指向 tenant_llm.id),与旧版用字符串模型名(embd_id/llm_id/asr_id 等)并存。这意味着 v0.17.2 的 tenant 记录不能直接复制到 v0.25.6——需要同时填充新旧两套字段。API 导入方式完全绕过了此问题。

3. 两版本数据库表关系对比

3.1 v0.17.2 核心表关系

User ──(user_id)──► UserTenant ◄──(tenant_id)── Tenant │ TenantLLM (LLM 模型) │ ▼ (embd_id 字符串引用) Knowledgebase ◄──(tenant_id) │ │ 1:N ▼ File ──(file_id)──► File2Document ◄──(document_id)── Document │ │ 1:N ▼ Task

3.2 v0.25.6 核心表关系(粗体=新增表)

User ──(user_id)──► UserTenant ◄──(tenant_id)── Tenant │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ TenantModelProvider TenantModelInstance TenantModel (拆自 TenantLLM) (拆自 TenantLLM) (拆自 TenantLLM) │ ▼ (tenant_embd_id 整数引用) Knowledgebase ◄──(tenant_id) │ ├── pipeline_id (可选) │ │ │ ▼ │ PipelineOperationLog (新增) │ │ 1:N ▼ File ──(file_id)──► File2Document ◄──(document_id)── Document │ │ │ ├── content_hash (新增) │ ├── suffix (新增) │ └── pipeline_id (新增) │ │ N:1 ▼ Connector ──► Connector2Kb (新增数据源) │ ▼ SyncLogs (新增同步日志)

3.3 LLM 模型表重构(v0.17.2 → v0.25.6 最大变化)

v0.17.2v0.25.6说明
TenantLLM
包含: tenant_id, llm_factory, llm_name, api_key, model_type 等全部字段
TenantModelProvider (provider_name, tenant_id)
TenantModelInstance (instance_name, provider_id, api_key)
TenantModel (model_name, provider_id, instance_id, model_type)
一张宽表拆成 Provider → Instance → Model 三张表,实现多 API Key、多模型管理

v0.25.6 官方提供了 tools/scripts/mysql_migration.py 来执行这个三步迁移(tenant_model_provider → tenant_model_instance → tenant_model),仅用于"原地升级"场景。API 导入方式无需执行此脚本。

4. 迁移后 ID 变化矩阵

本节说明通过 v0.25.6 REST API 重新创建后,各类标识符的保留/变化情况。

标识符v0.17.2 来源v0.25.6 目标是否保留说明
User ID user.id (32位 hex) v0.25.6 已有用户 ✅ 保留 前提:v0.25.6 中已预先创建了相同的用户(通过注册或导入)。API Key 绑定到用户,导入操作以该用户的 API Key 身份执行
Tenant ID tenant.id (32位 hex) v0.25.6 已有租户 ✅ 保留 前提:v0.25.6 中已预先创建了相同的租户。KB、File、Document 的 tenant_id 会自动关联到 API Key 所属租户
Knowledgebase ID knowledgebase.id (32位 hex) API 自动生成新 UUID ❌ 重新生成 API 创建 dataset 时不接受自定义 ID。MinIO 文件存储路径 (=kb_id) 因此变化,但 API 导入方式会重新上传文件到新路径,无影响
Document ID document.id (32位 hex) API 自动生成新 UUID ❌ 重新生成 上传文件时 API 内部生成新的 document ID。旧 ID 仅用于导出阶段关联 file2document
File ID file.id (32位 hex) API 自动生成新 UUID ❌ 重新生成 同 Document,File 也由 API 在内部创建
Chunk ID chunk.id (ES/Infinity 中的 _id) 重新解析后生成 ❌ 重新生成 重新解析会走新的 chunking pipeline,chunk 内容、数量、ID 都和旧版不同
Chunk 数量 document.chunk_num 重新解析后的值 ⚠️ 可能变化 v0.25.6 的 parser/chunking 逻辑有更新(如新增 context_size 参数),同一文件解析出的 chunk 数量可能增减。这是预期行为
API Token api_token.token v0.25.6 中的 API Key ❌ 需要新的 v0.25.6 API Key 需要在 v0.25.6 Web UI 中重新生成。旧 token 不能跨版本使用(JWT secret 不同,token 格式可能不同)
要点:除了 User ID 和 Tenant ID(需预先在新环境中创建),其他所有 ID(KB/Doc/File/Chunk/API Token)都是全新生成的。这意味迁移后无法通过旧 ID 查找新记录——需要依赖 KB 名称和文档名称进行核对。

5. 用户数据与知识库参数迁移

5.1 用户与租户迁移路径

数据v0.17.2 表迁移方式
用户账号 user (id, nickname, email, password, ...) 在 v0.25.6 中手动重新注册相同邮箱,或通过 POST /api/v1/users 创建。密码 hash 机制可能不兼容,不能直接复制。
租户 tenant (id, name, llm_id, embd_id, ...) 首次注册时自动创建默认 tenant(name = 用户昵称)。如需同名 tenant,可在 v0.25.6 中手动修改 tenant name。
用户-租户关联 user_tenant (user_id, tenant_id, role) v0.25.6 注册时自动建立关联。多租户场景需逐个添加。
API Token api_token (tenant_id, token) 在 v0.25.6 Web UI → API 页面重新生成。旧 token 不可用。
LLM 模型配置 tenant_llm (llm_factory, api_key, ...) 在 v0.25.6 Web UI 中重新配置模型提供商和 API Key。不能直接复制,因为表结构已拆成 3 张表。
建议的用户迁移顺序
① v0.25.6 中注册相同邮箱的用户 → ② 获取 API Key → ③ 执行 KB 迁移脚本(export + import)→ ④ 重新配置 LLM 模型

5.2 知识库参数设置迁移

v0.17.2 的 KB 参数可通过 API 在创建或更新 dataset 时传入:

v0.17.2 参数v0.25.6 API 字段迁移策略
knowledgebase.name name 直接传递(同名 dataset 复用)
knowledgebase.description description 直接传递
knowledgebase.permission permission ("me" | "team") 直接传递。v0.17.2 默认 "me",v0.25.6 语义一致
knowledgebase.parser_id chunk_method 映射表转换(见下方)
knowledgebase.parser_config parser_config 直接传递,API 自动补全缺失的默认键。v0.25.6 新增 table_context_sizeimage_context_size 将使用默认值 0
knowledgebase.embd_id embedding_model 直接传递。如不传则使用 tenant 默认值
knowledgebase.pagerank pagerank (via PUT update) 创建后再用 PUT /datasets/{id} 设置
knowledgebase.similarity_threshold v0.25.6 不在 dataset 级别的 API 暴露。在 Search 对象中配置
knowledgebase.vector_similarity_weight 同上,在 Search 对象中配置

parser_id → chunk_method 映射表

v0.17.2 parser_idv0.25.6 chunk_method
naivenaive
bookbook
emailemail
lawslaws
manualmanual
oneone
paperpaper
picturepicture
presentationpresentation
qaqa
tabletable
tagtag
resumeresume
knowledge_graphknowledge_graph
知识库参数通过 POST /api/v1/datasets 创建时携带,或创建后通过 PUT /api/v1/datasets/{id} 更新。脚本默认使用 v0.25.6 API 的默认参数(naive chunking,tenant 默认 embedding),如需保留旧参数,可在 manifest.json 中扩展对应字段。

6. 迁移架构

v0.17.2
MySQL
读取 KB
+ Doc
+ File
v0.17.2
MinIO
下载
文件
manifest.json
+ files/
v0.25.6
REST API
v0.25.6
MySQL

Phase 1 (export_files.py) ⸻⸻⸻⸻⸻⸻⸻⸻⸻⸻⸻⸻⸻⸻ Phase 2 (import_to_v0256.py) ⸻⸻⸻⸻⸻⸻⸻ Phase 3 (verify_migration.py)

6.1 输出结构

${temp_dir}/
├── manifest.json           # KB 列表 + 文件映射
└── files/
    ├── 产品文档_a1b2c3d4/  # {kb_name}_{kb_id前8位} 防同名
    │   ├── 需求规格.pdf
    │   └── 用户手册.docx
    └── 技术资料_e5f6g7h8/
        └── 架构设计.pdf

6.2 manifest.json

[
  {
    "kb_id": "a1b2c3d4e5f6...",
    "kb_name": "产品文档",
    "kb_description": "...",
    "files": [
      {"name": "需求规格.pdf", "local_path": "files/产品文档_a1b2c3d4/需求规格.pdf"}
    ]
  }
]

6.3 边界情况处理

场景处理
KB 同名目录名追加 kb_id 前8位: {name}_{id[:8]};manifest 以 kb_id 为主键
文件重名(同 KB 内)自动加 _1, _2 后缀
document.location 为空跳过并 warning
MinIO 下载失败记录 error,继续处理其他文件
无 file2document 关联使用 document.name 作为文件名
dataset 已存在复用已有 ID,不重复创建
API 返回非 0 code抛异常,该 batch 整体失败

7. Phase 1 — 导出 (export_files.py)

数据查询链路

SELECT id, name, description FROM knowledgebase WHERE status='1'
       ↓ 对每个 kb_id
SELECT id, name, location, type FROM document WHERE kb_id=? AND status='1'
       ↓
SELECT document_id, file_id FROM file2document WHERE document_id IN (...)
       ↓
SELECT id, name FROM file WHERE id IN (...)
       ↓
MinIO: fget_object(bucket=kb_id, key=doc.location, local_path)

8. Phase 2 — 导入 (import_to_v0256.py)

API 调用时序

# Step 1: 检查已有 datasets(避免重复创建)
GET /api/v1/datasets?page=1&page_size=1000

# Step 2: 对每个 KB(如不存在则创建)
POST /api/v1/datasets
  Body: {"name": "产品文档", "description": "..."}

# Step 3: 批量上传文件(自动触发解析)
POST /api/v1/datasets/{dataset_id}/documents
  Content-Type: multipart/form-data
  Body: file=@需求规格.pdf, file=@用户手册.docx

9. Phase 3 — 核对 (verify_migration.py)

核对维度(数量级)

维度目标判定
KB 数量manifest 条目数GET /datasets 返回数相等
文档数量每个 entry 的 files.lenGET /datasets/{id}/documents逐 KB 相等
解析状态document.run 字段DONE/FAIL/PENDING 分布

10. 解析内容验证

迁移后需要验证文档确实被正确解析检索可用。验证分三个层次:

10.1 基础验证:文档状态 & 分块数量

验证项方法预期
文档解析完成 GET /api/v1/datasets/{id}/documents 检查 run 字段 run = "DONE" (或 "1"),progress = 1.0
分块数 > 0 同上接口,检查 chunk_count 字段 chunk_count > 0(非空文档)
token 数 > 0 检查 token_count 字段 token_count > 0

10.2 中级验证:分块内容抽样

  1. 按 chunk_method 分类抽样:每种 parser 类型各抽 2-3 个文档
  2. 调用检索 API
    POST /api/v1/searches
    Body: {
      "dataset_ids": ["{id}"],
      "query": "文档中的关键字或摘要句",
      "top_k": 5
    }
    → 返回 [{content, score, document_name, ...}]
  3. 人工检查:返回的 chunk content 是否语义相关、文本是否完整(无截断、无乱码)
  4. 对比旧版:如有 v0.17.2 仍可查询,用相同 query 对比两个版本返回的 chunk 数量和内容相似度

10.3 深度验证:全量统计对比(脚本化)

验证项方法异常判断
空文档检测 chunk_count = 0 且 run = DONE 的文档 原文件有内容但解析出 0 chunk → parser 问题
异常大文档 单个文档 chunk_count > 平均值 × 3 可能是重复内容或 parser 没有正确分段
解析失败率 FAIL / 总文档数 > 5% 需要排查
每 KB 检索可达性 对每个 KB 发送一个泛化 query(如 KB name),检查是否返回结果 0 结果 → 索引可能未建立
建议:在 verify_migration.py 中增加 --deep 模式,对每个 KB 自动发送检索请求并报告 chunk_count 分布的统计摘要(min/max/avg/median)。此功能可在基础核对通过后执行。

11. 权限验证

11.1 权限模型对比

两个版本的权限模型基本一致

维度v0.17.2v0.25.6变化
KB 权限粒度 me / team me / team 一致
权限检查函数 check_kb_permission check_kb_team_permission 函数重构:逻辑相同,增加了 TenantPermission 枚举
租户内权限 UserTenant.role (NORMAL/ADMIN) 一致
API 认证 Bearer token (api_token) Bearer token (API Key) token 格式不同,需重新生成

11.2 权限验证清单

#验证场景操作预期结果
1 KB 创建者可访问 用创建 KB 的用户的 API Key 调用 GET /datasets/{id} ✅ 返回 KB 详情
2 permission=me 的 KB 对其他用户不可见 另一个用户的 API Key 调用 GET /datasets/{id} ✅ 返回空或 403
3 permission=team 的 KB 对同 tenant 其他用户可见 用同 tenant 下另一个用户的 API Key 调用 GET /datasets ✅ 列表中包含该 KB
4 team KB 对不同 tenant 用户不可见 用不同 tenant 用户的 API Key 调用 GET /datasets/{id} ✅ 返回空或 403
5 API Key 可正常使用检索 POST /api/v1/searches 对迁移的 KB 进行检索 ✅ 返回相关 chunk

11.3 权限迁移注意事项

12. 配置文件说明

# config.yaml
source:
  mysql:
    host: "localhost"
    port: 3306
    user: "root"
    password: ""
    database: "rag_flow"
  storage:
    type: "minio"
    host: "localhost:9000"
    access_key: "minioadmin"
    secret_key: "minioadmin"
    secure: false

target:
  base_url: "http://localhost:9380"
  api_key: "ragflow-xxxx"       # 从 v0.25.6 Web UI → API 获取
  timeout: 300

temp_dir: "/tmp/ragflow_migration"
batch_size: 10

13. 执行手册

前置条件

#条件检查方式
1v0.17.2 MySQL 可访问mysql -h <host> -u <user> -p -e "SELECT 1"
2v0.17.2 MinIO 可访问curl http://<host>:9000/minio/health/live
3v0.25.6 服务运行中curl http://<host>:9380/api/v1/datasets -H "Authorization: Bearer <key>"
4用户已在 v0.25.6 中注册获取 API Key: Web UI 右上角 → API
5磁盘空间充足源文件总大小 × 1.2 的临时空间

执行步骤

# Step 0: 准备
cd tools/scripts/migrate_v0172_to_v0256
vim config.yaml           # 填实际参数
pip install -r requirements.txt

# Step 1: 导出
python export_files.py -c config.yaml
  # 检查输出: /tmp/ragflow_migration/manifest.json

# Step 2: 导入
python import_to_v0256.py -c config.yaml
  # 文件上传成功后会立即触发解析

# Step 3: 基础核对
python verify_migration.py -c config.yaml
  # 如 PENDING 数 > 0,等待后重跑

# Step 4: 内容验证(手动/半自动)
  # 4a. 检查 FAIL 状态的文档
  # 4b. 抽样检索验证 chunk 质量
  # 4c. 对比 source/target chunk_count 分布

# Step 5: 权限验证
  # 5a. 用不同用户 API Key 测试 me/team 隔离
  # 5b. 确认检索 API 可用

执行时间估算

阶段耗时因素示例 (100文件, 1GB)
导出MinIO 下载带宽~2-5 分钟
导入HTTP 上传~3-10 分钟
解析Worker 处理(后台异步)几分钟到数小时

14. 常见问题与回滚

问题原因解决
pymysql.err.OperationalErrorMySQL 连接失败检查 config.yaml source.mysql 参数
minio.error.S3ErrorMinIO 凭证或 bucket 不存在检查 access_key/secret_key;bucket=kb_id
API error code=102API Key 无效从 v0.25.6 Web UI 重新获取
文件解析 FAIL格式不兼容检查 v0.25.6 支持的文件类型;手动尝试
核对文档数不一致部分上传失败查看日志;重跑 Phase 2
检索无结果索引未建立或 embedding 模型未配置确认 v0.25.6 中已配置 Embedding 模型
权限不生效用户未加入对应 tenant检查 UserTenant 表关联

回滚

本方案不修改 v0.17.2 任何数据,回滚非常简单:

  1. 删除 v0.25.6 中的 datasets — Web UI 或 DELETE /api/v1/datasets
  2. rm -rf /tmp/ragflow_migration
  3. v0.17.2 原环境完全不受影响

RAGFlow v0.17.2 → v0.25.6 Migration Design  ·  v2.0  ·  tools/scripts/migrate_v0172_to_v0256/