🔄 RAGFlow 数据迁移兼容性报告

用户数据 / 知识库数据 / API 接口兼容性评估
源版本: v0.17.2 目标版本: v0.25.6 评估日期: 2026-06-17
总体评估:基本兼容,需注意 3 项操作步骤
用户 ID / 密码 / API Token 直接迁移可用,知识库数据完整保留。但有 2 个需要手动干预的场景。
兼容 — 无需操作 注意 — 需确认 / 自动修复 需手动 — 必须人工处理

📊 核心兼容性矩阵

数据/场景兼容级别详细说明用户操作
👤 用户账号 + 密码 ✅ 直接兼容 密码哈希算法完全一致(Werkzeug pbkdf2:sha256),v0.17.2 的密码可在 v0.25.6 直接验证登录。
⚠️ 如有重复 email 用户,migration 会自动重命名:dup@x.comdup@x.com_DUPLICATE_{id前8位}
无需操作
🔐 用户登录 Session ⚠️ 需重新登录 v0.17.2 的 SECRET_KEY 默认为 str(date.today())(每日变化), v0.25.6 改为 Redis 持久化的 secrets.token_hex(32)。 旧的 JWT Authorization token 无法在新密钥下解码。 用户需重新登录
🔑 已有 API Token ✅ 直接兼容 API Token 存储在 api_token 表中作为纯字符串精确匹配查询。 v0.17.2 创建的 token(格式 ragflow-...)迁移后仍能通过已有值查询匹配。
🟡 但旧 token 无法重新生成 — 新版本 generate_confirmation_token() 签名已变。
无需操作
🔑 新创建 API Token 🟡 格式变化 v0.17.2: ragflow- + JWT (依赖 tenant_id 作为密钥)
v0.25.6: ragflow- + secrets.token_urlsafe(32)(纯随机)
新旧 token 共享同一表但格式不同,接口查询方式不变(均通过 APIToken.query(token=token)
新 token 格式不同,不影响功能
📚 知识库 ID + 配置 ✅ 直接兼容 ID 生成算法一致(uuid.uuid1().hex)。 ParserType 枚举值完全兼容(14 个值一致)。 parser_config 新增字段向后兼容(table_context_sizeimage_context_size,默认 0)。 无需操作
📄 文档数据 ✅ 直接兼容 process_duationprocess_duration 列重命名(数据保留,原子操作)。 size IntegerField → BigIntegerField(无截断)。 新增 pipeline_idsuffixcontent_hash 为 nullable。 无需操作
🏢 TenantLLM 模型配置 ✅ 自动迁移 主键从 复合键 (tenant_id, llm_factory, llm_name)自增整数 idmigrate_db() 自动分配 ID(按原顺序),旧复合键作为 UNIQUE 约束保留。 fix_empty_tenant_model_id() 自动填充所有新 FK 引用。 无需操作
💬 Dialog / 对话配置 🟡 需要 init 新增 tenant_llm_idtenant_rerank_id FK 字段。 v0.25.6 启动时 fix_empty_tenant_model_id() 自动从旧的 llm_id/rerank_id 字符串反查填充。 旧的字符串引用保留为 fallback。 启动后自动修复
📁 文件数据 ✅ 直接兼容 size IntegerField → BigIntegerField,无其他变更。 无需操作
🖼️ Canvas / Agent 画布 🟡 特性扩展 新增 permissionreleasecanvas_categorytags 字段。 旧数据默认值安全(permission="me", release=False, category="agent_canvas")。 CanvasTemplate 的 title/description 从 TextField → JSONField(多语言),旧文本数据需注意。 旧 Canvas 数据可正常使用
🔍 Re-Rank / 检索接口 ✅ 向后兼容 tenant.rerank_iddialog.rerank_id 的字符串引用保留。 新增的 tenant_rerank_id 为 nullable,不影响旧查询。 无需操作

👤 用户认证兼容性详解

2.1 密码哈希 — 完全兼容 ✅

项目v0.17.2v0.25.6兼容性
哈希函数 werkzeug.security.generate_password_hash() werkzeug.security.generate_password_hash() 完全相同
哈希算法 pbkdf2:sha256(Werkzeug 默认) pbkdf2:sha256(Werkzeug 默认) 完全相同
验证函数 werkzeug.security.check_password_hash() werkzeug.security.check_password_hash() 完全相同
密码字段 CharField(max_length=255, null=True) CharField(max_length=255, null=True) 完全相同
结论:v0.17.2 中已哈希的密码可以直接在 v0.25.6 中验证,无需任何迁移操作。用户用原密码即可登录。

2.2 User ID — 完全兼容 ✅

项目v0.17.2v0.25.6兼容性
ID 生成 uuid.uuid1().hex uuid.uuid1().hex 完全相同
ID 字段 CharField(max_length=32, primary_key=True) CharField(max_length=32, primary_key=True) 完全相同
access_token 格式 uuid.uuid1().hex(登录时重新生成) uuid.uuid1().hex(登录时重新生成) 完全相同
access_token 存储 CharField(max_length=255, null=True) CharField(max_length=255, null=True) 完全相同
email 约束 index=True unique=True ⚠️ 需检查重复 email

2.3 Email 唯一约束迁移 — 需确认 🟡

v0.25.6 将 user.email 从普通索引升级为 UNIQUE 约束。迁移函数 migrate_add_unique_email() 会自动处理:

  1. 检测所有重复 email
  2. 保留 superuser最早创建 的账号
  3. 其余重复账号重命名为 {email}_DUPLICATE_{id[:8]}
  4. 添加 UNIQUE 约束
-- 迁移前
user1: admin@x.com  (superuser, 最早) → 保留
user2: admin@x.com                   → admin@x.com_DUPLICATE_a1b2c3d4

-- 日志输出
WARNING: Renamed duplicate user a1b2c3d4 email to admin@x.com_DUPLICATE_a1b2c3d4 during migration
建议:迁移前先检查是否有重复 email:
SELECT email, COUNT(*) FROM user GROUP BY email HAVING COUNT(*) > 1;

2.4 登录认证框架变更 — 需重新登录 🔴

项目v0.17.2v0.25.6影响
认证框架 Flask-Login (UserMixin) Quart-Auth (AuthUser) 框架级变更
SECRET_KEY 存储 配置文件 secret_key Redis ragflow:system:secret_key 密钥完全不同
SECRET_KEY 默认值 str(date.today())(如 "2025-03-13" secrets.token_hex(32)(64 字符随机 hex) 格式完全不同
JWT 签名算法 URLSafeTimedSerializer(secret_key) URLSafeTimedSerializer(secret_key) 算法相同
get_id() 方法 jwt.dumps(str(self.access_token)) jwt.dumps(str(self.access_token)) 逻辑相同
登出 token 处理 设置为空字符串 "" 设置为 "INVALID_" + secrets.token_hex(16) 安全改进,不影响迁移
结论:由于 SECRET_KEY 在升级后变化,所有在 v0.17.2 中登录的用户 session(JWT Authorization token)将在 v0.25.6 中失效。 用户必须重新登录。这不影响数据库中的用户数据,仅影响已登录的会话。

📚 知识库数据迁移详解

3.1 ID 和关键字段兼容性 ✅

检查项v0.17.2v0.25.6兼容性
KB ID 生成uuid.uuid1().hexuuid.uuid1().hex相同
Document ID 生成uuid.uuid1().hexuuid.uuid1().hex相同
File ID 生成uuid.uuid1().hexuuid.uuid1().hex相同
Task ID 生成uuid.uuid1().hexuuid.uuid1().hex相同
ParserType 枚举14 个值14 个值(完全一致)相同
KB tenant_idCharField(32)CharField(32)相同
Document kb_idCharField(256)CharField(256)相同
File2Document 映射file_id + document_idfile_id + document_id相同

3.2 Knowledgebase 表新增字段

新增字段类型默认值对旧数据影响
tenant_embd_idIntegerField, nullable, indexNULL启动后 auto-fix 填充
pipeline_idCharField(32), nullable, indexNULL可选字段,不影响
graphrag_task_idCharField(32), nullableNULL新功能,不影响
graphrag_task_finish_atDateTimeField, nullableNULL新功能,不影响
raptor_task_idCharField(32), nullableNULL新功能,不影响
raptor_task_finish_atDateTimeField, nullableNULL新功能,不影响
mindmap_task_idCharField(32), nullableNULL新功能,不影响
mindmap_task_finish_atDateTimeField, nullableNULL新功能,不影响

3.3 TenantLLM 主键重构及其影响

这是本次升级最核心的架构变更,影响所有引用 LLM 模型的表:

阶段操作数据安全
1. 添加临时列 ALTER TABLE tenant_llm ADD COLUMN temp_id INT NULL 不丢失数据
2. 顺序编号 UPDATE tenant_llm SET temp_id = row_number ORDER BY tenant_id, llm_factory, llm_name 确定性排序
3. 删除旧主键 ALTER TABLE tenant_llm DROP PRIMARY KEY 列值保留
4. 设置新主键 temp_id → NOT NULL AUTO_INCREMENT PRIMARY KEY 数据完整
5. 保留唯一性 ADD UNIQUE (tenant_id, llm_factory, llm_name) 旧约束保留
6. 重命名列 RENAME COLUMN temp_id TO id 完成

3.4 FK 自动填充机制

v0.25.6 启动时 fix_empty_tenant_model_id() 自动执行以下映射:

-- 伪代码逻辑
# Tenant: 填充 6 个 FK
UPDATE tenant t
SET t.tenant_llm_id = (SELECT tl.id FROM tenant_llm tl
    WHERE tl.tenant_id = t.id AND tl.llm_name = t.llm_id)
WHERE t.tenant_llm_id IS NULL;

# Knowledgebase: 填充 tenant_embd_id
UPDATE knowledgebase kb
SET kb.tenant_embd_id = (SELECT tl.id FROM tenant_llm tl
    WHERE tl.tenant_id = kb.tenant_id AND tl.llm_name = kb.embd_id)
WHERE kb.tenant_embd_id IS NULL;

# Dialog: 填充 tenant_llm_id 和 tenant_rerank_id
UPDATE dialog d
SET d.tenant_llm_id = (SELECT tl.id FROM tenant_llm tl
    WHERE tl.tenant_id = d.tenant_id AND tl.llm_name = d.llm_id)
WHERE d.tenant_llm_id IS NULL;

# Memory: 填充 tenant_embd_id 和 tenant_llm_id
UPDATE memory m SET ... WHERE m.tenant_embd_id IS NULL;
注意:填充过程需要 v0.25.6 首次启动后自动运行。如果旧字符串引用(如 llm_id)对应的 TenantLLM 记录不存在,该 FK 将保持 NULL,系统会回退使用 tenant 级别的默认模型。

3.5 字段重命名 — 数据完整保留 ✅

旧字段名新字段名迁移方式数据安全
documentprocess_duationprocess_durationALTER TABLE RENAME COLUMN原子操作,数据保留
taskprocess_duationprocess_durationALTER TABLE RENAME COLUMN原子操作,数据保留

3.6 字段类型变更 — 无截断风险 ✅

字段旧类型新类型风险评估
documentsizeIntegerFieldBigIntegerField向上兼容,无截断
filesizeIntegerFieldBigIntegerField向上兼容,无截断
tenant_llmapi_keyCharField(1024)TextField向上兼容,无截断
canvas_templatetitleCharField(255)JSONField旧纯文本值变为 JSON 字符串
canvas_templatedescriptionTextFieldJSONField旧纯文本值变为 JSON 字符串
Canvas Template 注意:旧 title 如 "My Agent" 在 JSONField 中会作为 JSON 字符串 "My Agent" 存储。新代码期望 {"en": "...", "zh": "..."} 格式,需确认模板是否正确显示。不影响数据完整性,仅影响多语言功能。

🔑 API 接口兼容性详解

4.1 API Token 认证兼容性

场景兼容级别说明
已有 API Token 访问检索接口 ✅ 直接可用 API Token 在 api_token 表中作为纯字符串存储,通过 APIToken.query(token=token) 精确匹配。v0.17.2 创建的 token(如 ragflow-eyJhbGciOi...)迁移后仍然可以匹配。
新建 API Token 🟡 格式变化 新 token 格式从 JWT 变为纯随机字符串,但功能完全相同。
旧: ragflow-eyJzb21ld... (JWT, 依赖 tenant_id 作密钥)
新: ragflow-DkR8xZq3vN7... (43 字符 base64url 随机)
API Token + 密码 Basic Auth ✅ 兼容 密码哈希不变。API 接口支持 token 或 Basic Auth 两种方式。
API Token 的 beta 字段 ✅ 兼容 存储在 DB 中的 beta 值直接迁移。v0.25.6 中如 beta 为空,启动时会用新算法重新生成。

4.2 检索/搜索接口兼容性

接口路径认证方式v0.17.2 → v0.25.6 兼容性
知识库检索 /api/v1/retrieval Authorization: Bearer {api_token} ✅ Token 字符串直接可用
对话 API /api/v1/new_token 登录后获取 🟡 新 token 格式不同
文档上传 API /api/v1/document/upload Authorization: Bearer {api_token} ✅ Token 字符串直接可用
文件管理 API /api/v1/dataset/* Authorization: Bearer {api_token} ✅ Token 字符串直接可用
SDK 连接 ragflow_client = RAGFlow(api_key, base_url) api_key (即 token) ✅ 已有 api_key 直接可用

4.3 API Token 验证流程对比

v0.17.2 验证流程:

# api/utils/api_utils.py
def token_required(f):
    token = request.headers.get('Authorization').split()[1]
    obj = APIToken.query(token=token)  # 直接查表
    if not obj:
        return get_error_data_result("Authentication failed")

v0.25.6 验证流程:

# api/utils/api_utils.py (line 288+)
def token_required(f):
    token = request.headers.get('Authorization').split()[1]
    obj = APIToken.query(token=token)  # 先查表(与旧版相同)
    if obj:
        # token 有效
        return f(...)
    # 回退:尝试 JWT 解码(兼容旧 login token)
    user = UserService.query(access_token=token)
    ...
关键发现:v0.25.6 的 token_required 新增了 JWT 回退逻辑。旧的 API Token(存储在 api_token 表中作为字符串)仍然通过第一优先级APIToken.query(token=token) 精确匹配验证。因此已有 API Token 在迁移后立即可用,无需重新创建

4.4 Token 格式差异对比

属性v0.17.2 Tokenv0.25.6 Token
生成函数generate_confirmation_token(tenant_id)generate_confirmation_token()
生成算法"ragflow-" + URLSafeTimedSerializer(tenant_id).dumps(uuid)[2:34]"ragflow-" + secrets.token_urlsafe(32)
长度约 40 字符约 51 字符
示例ragflow-eyJzb21ldGhpbmdfbG9uZ19hbmRfYmFzZTY0ragflow-DkR8xZq3vN7pLmW2sA5bFyU1cQ6tG4hJ
安全性中等(基于 tenant_id UUID 作为密钥)高(基于操作系统 CSPRNG)
DB 存储纯字符串纯字符串
DB 查询APIToken.query(token=token)APIToken.query(token=token)

📋 迁移操作指南

预备检查清单

#检查项命令/操作预期
1检查重复 email SELECT email, COUNT(*) FROM user GROUP BY email HAVING COUNT(*) > 1; 返回空或少量。非空时迁移会重命名 duplicates
2检查腾讯LLM记录 SELECT COUNT(*) FROM tenant_llm; 应当 > 0。空表也可迁移,FK 值将为 NULL
3检查知识库数量 SELECT COUNT(*) FROM knowledgebase WHERE status='1'; 确认有效 KB 数量
4备份数据库 mysqldump -u root -p ragflow > ragflow_backup_$(date +%Y%m%d).sql 必须操作!
5检查 ES/Infinity 索引 确认 chunks 索引存在且可查询 ES 索引与 DB 无关,但升级后需确认映射兼容

迁移步骤

1
备份所有数据
# 完整数据库备份
mysqldump -u root -p ragflow > ragflow_v0172_backup.sql

# 如果使用 PostgreSQL
pg_dump -U ragflow ragflow > ragflow_v0172_backup.sql
2
停止 v0.17.2 服务
cd /path/to/ragflow-0.17.2/docker
docker compose down
3
启动 v0.25.6 基础设施
cd /path/to/ragflow-0.25.6/docker
docker compose -f docker-compose-base.yml up -d
# 等待 MySQL/Redis/ES/MinIO 全部 healthy
docker compose ps
确保 MySQL 数据卷指向旧数据库目录,或已导入旧数据。
4
启动 v0.25.6 服务(首次自动迁移)
docker compose -f docker-compose.yml up -d
# 监控启动日志
docker logs -f ragflow-server

服务启动时自动执行 init_database_tables()migrate_db()fix_empty_tenant_model_id()

5
验证迁移结果
# 查看日志中的迁移信息
docker logs ragflow-server 2>&1 | grep -E "(migrat|DUPLICATE|fix_empty|tenant_llm)"

# 验证用户数据
SELECT COUNT(*), COUNT(DISTINCT email) FROM user;

# 验证 FK 填充
SELECT COUNT(*) FROM tenant WHERE tenant_llm_id IS NOT NULL;
SELECT COUNT(*) FROM knowledgebase WHERE tenant_embd_id IS NOT NULL;
SELECT COUNT(*) FROM dialog WHERE tenant_llm_id IS NOT NULL;
6
验证功能
  • 用管理员账号登录 Web UI
  • 检查知识库列表是否完整
  • 用已有 API Token 调用 /api/v1/retrieval 验证检索
  • 测试文档上传和解析功能
  • 验证 Agent Canvas 是否正常加载

回滚方案

!
如果迁移失败:
# 1. 停止 v0.25.6
docker compose down -v

# 2. 恢复数据库备份
mysql -u root -p ragflow < ragflow_v0172_backup.sql

# 3. 重新启动 v0.17.2
cd /path/to/ragflow-0.17.2/docker
docker compose up -d
注意:回滚后所有在 v0.25.6 中创建的新数据将丢失。迁移前的备份至关重要。