# Schema 迁移方案：新库 knowhub

> 历史记录：这是 v3 一次性迁移（knowledge_hub → knowhub）的方案。**跑 DDL 前的通用规范**参见 [db-operations.md](./db-operations.md)。

## 背景

旧库 `knowledge_hub` 使用 JSONB 数组存储实体间关系，存在一致性、索引、命名问题。迁移目标：在新库 `knowhub` 中建立干净的关联表结构。

### 为什么新建库而不是原地改

阿里云 AnalyticDB for PostgreSQL 的 DDL 限制（已验证）：

| 操作 | 是否安全 | 说明 |
|------|---------|------|
| CREATE TABLE | ✅ 安全 | 包括 IF NOT EXISTS |
| DROP TABLE | ✅ 安全 | 已验证可用 |
| INSERT / SELECT | ✅ 安全 | 包括 ON CONFLICT DO NOTHING |
| ALTER TABLE RENAME | ❌ 致命 | 导致表损坏，需重启实例恢复 |
| ALTER TABLE DROP COLUMN | ❌ 致命 | 同上 |
| FK / ON DELETE CASCADE | ❌ 不支持 | 底层依赖 trigger，而 trigger 不被支持 |
| 事务内 DDL | ❌ 不可靠 | DDL 回滚不完整，部分操作会持久化 |

**改表结构的安全方式**：CREATE TABLE 新表 → INSERT 数据 → DROP TABLE 旧表。

原地迁移多次失败后，决定新建库 `knowhub`，用 CREATE TABLE + INSERT 完成迁移。旧库保留作为备份。

## 目标结构

见 `schema.md`。5 实体表 + 8 关联表 = 13 张表。

## 旧库现状（2026-04-08）

| 旧表 | 状态 | 说明 |
|------|------|------|
| `knowledge` (766 rows) | 可用 | 仍含 support_capability、tools、resource_ids、relationships 旧字段 |
| `tool` (305 rows) | 可用 | 原 tool_table，被 RENAME；JSONB 关联列已丢失 |
| `capability` / `atomic_capability` (21 rows) | 可用 | 两个名字同时可访问 |
| `requirement` / `requirement_table` (99 rows) | 可用 | 两个名字同时可访问 |
| `resources` (73 rows) | 可用 | 无变化 |
| `requirement_capability` (214 rows) | 可用 | 旧迁移已填充 |
| `capability_tool` (67 rows) | 可用 | 旧迁移已填充（仅 capability 侧） |
| `capability_knowledge` (0 rows) | 可用 | 源数据为空 |
| `tool_knowledge` (846 rows) | 可用 | 旧迁移已填充 |

## 新库迁移步骤

### Step 1：在 knowhub 库建 13 张表

只用 CREATE TABLE IF NOT EXISTS，不用 ALTER/RENAME/DROP。

### Step 2：迁移实体数据

从 knowledge_hub 读 → 写入 knowhub。每张表只选需要的列：

| 新表 | 源表 | 选取列（排除的旧字段） |
|------|------|----------------------|
| knowledge | knowledge | 排除 support_capability, tools, resource_ids, relationships |
| resource | resources | 全部 |
| requirement | requirement | 排除 atomics |
| capability | capability | 排除 requirements, implements, tools, source_knowledge |
| tool | tool | 排除 implemented_tool_ids（已无 JSONB 关联列） |

### Step 3：迁移关联数据

**从旧关联表直接复制**（已有正确数据）：
- requirement_capability (214 rows)
- capability_tool (67 rows)
- tool_knowledge (846 rows)

**从旧 JSONB 字段提取**（新增的关联表）：
- requirement_knowledge — 从 requirement 和 knowledge 的关联提取（如有）
- knowledge_resource — 从 knowledge.resource_ids 数组提取
- knowledge_relation — 从 knowledge.relationships JSONB 提取
- tool_provider — 需手动或从工具库数据填充

**无数据需迁移**：
- capability_knowledge — 源数据为空

### Step 4：验证

对比新旧库行数，确认数据完整。

### Step 5：切换

更新 .env 中 `KNOWHUB_DB_NAME=knowhub`，重启服务。

## 代码改动范围

- `knowhub_db/pg_*.py`：所有 store 适配新表结构
- `knowhub_db/cascade.py`：更新关联表注册
- `knowhub/server.py`：Pydantic 模型和 API handler
- `knowhub/agents/librarian_agent.prompt`：schema 描述
- `.env`：KNOWHUB_DB_NAME

## 迁移脚本

`knowhub/knowhub_db/migrations/migrate_to_new_db.py`
