Files
AIclinicalresearch/docs/04-开发规范/09-数据库开发规范.md
HaHafeng 2481b786d8 deploy: Complete 0126-27 deployment - database upgrade, services update, code recovery
Major Changes:
- Database: Install pg_bigm/pgvector plugins, create test database
- Python service: v1.0 -> v1.1, add pymupdf4llm/openpyxl/pypandoc
- Node.js backend: v1.3 -> v1.7, fix pino-pretty and ES Module imports
- Frontend: v1.2 -> v1.3, skip TypeScript check for deployment
- Code recovery: Restore empty files from local backup

Technical Fixes:
- Fix pino-pretty error in production (conditional loading)
- Fix ES Module import paths (add .js extensions)
- Fix OSSAdapter TypeScript errors
- Update Prisma Schema (63 models, 16 schemas)
- Update environment variables (DATABASE_URL, EXTRACTION_SERVICE_URL, OSS)
- Remove deprecated variables (REDIS_URL, DIFY_API_URL, DIFY_API_KEY)

Documentation:
- Create 0126 deployment folder with 8 documents
- Update database development standards v2.0
- Update SAE deployment status records

Deployment Status:
- PostgreSQL: ai_clinical_research_test with plugins
- Python: v1.1 @ 172.17.173.84:8000
- Backend: v1.7 @ 172.17.173.89:3001
- Frontend: v1.3 @ 172.17.173.90:80

Tested: All services running successfully on SAE
2026-01-27 08:13:27 +08:00

513 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据库开发规范
> 版本: v2.0
> 更新日期: 2026-01-26
> 重要更新: 统一使用 Prisma Schema 管理所有数据库变更
---
## 📢 核心原则
```
┌─────────────────────────────────────────────────────────────────────┐
│ 🎯 统一原则:所有数据库变更必须通过 Prisma Schema 管理 │
│ │
│ ✅ 使用 prisma migrate dev/deploy 进行变更 │
│ ❌ 禁止直接执行手工 SQL 修改表结构 │
│ ❌ 禁止使用 prisma db push仅用于原型开发
└─────────────────────────────────────────────────────────────────────┘
```
---
## 1. 开发流程规范
### 1.1 标准开发流程(必须遵循)
```
┌─────────────────────────────────────────────────────────────────────┐
│ 数据库变更标准流程 │
└─────────────────────────────────────────────────────────────────────┘
开发阶段 部署阶段
──────── ────────
┌─────────────────┐ ┌─────────────────┐
│ 1. 修改 schema.prisma │ │ 1. 代码合并到主分支 │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 2. npx prisma migrate dev │ │ 2. 备份生产数据库 │
│ --name feature_name │ └────────┬────────┘
└────────┬────────┘ │
│ ▼
▼ ┌─────────────────┐
┌─────────────────┐ │ 3. npx prisma migrate deploy │
│ 3. 检查生成的迁移SQL │ └────────┬────────┘
└────────┬────────┘ │
│ ▼
▼ ┌─────────────────┐
┌─────────────────┐ │ 4. 验证 & 测试 │
│ 4. 本地测试 │ └─────────────────┘
└────────┬────────┘
┌─────────────────┐
│ 5. 提交代码 + 迁移文件 │
└─────────────────┘
```
### 1.2 命令使用规范
| 场景 | 命令 | 说明 |
|------|------|------|
| **开发时新增/修改表** | `npx prisma migrate dev --name xxx` | ✅ 生成迁移文件 |
| **生产环境部署** | `npx prisma migrate deploy` | ✅ 应用未执行的迁移 |
| **生成 Prisma Client** | `npx prisma generate` | ✅ 更新类型定义 |
| **检查迁移状态** | `npx prisma migrate status` | ✅ 查看待迁移列表 |
| **验证 Schema** | `npx prisma validate` | ✅ 检查语法错误 |
### 1.3 禁止使用的命令
| 命令 | 危险等级 | 原因 |
|------|----------|------|
| `prisma db push` | 🟠 **高** | 不生成迁移文件,无法追踪变更历史 |
| `prisma db push --force-reset` | 🔴 **极高** | 会删除所有数据 |
| `prisma migrate reset` | 🔴 **极高** | 重置整个数据库 |
| 手工执行 `ALTER TABLE` | 🟠 **高** | 导致 Schema 与数据库不一致 |
| 手工执行 `CREATE TABLE` | 🟠 **高** | 导致 Schema 与数据库不一致 |
---
## 2. Schema 变更示例
### 2.1 新增表
```prisma
// 1. 在 schema.prisma 中添加模型
model NewFeature {
id String @id @default(uuid())
name String
createdAt DateTime @default(now()) @map("created_at")
@@map("new_features") // 表名使用下划线
@@schema("feature_schema") // 指定 Schema
}
```
```bash
# 2. 生成迁移
npx prisma migrate dev --name add_new_feature_table
# 3. 检查生成的 SQL
cat prisma/migrations/xxx_add_new_feature_table/migration.sql
```
### 2.2 新增字段
```prisma
// 1. 在模型中添加字段
model User {
id String @id
email String
phone String? // 新增字段,可为空
createdAt DateTime @default(now())
@@schema("platform_schema")
}
```
```bash
# 2. 生成迁移
npx prisma migrate dev --name add_user_phone_field
```
### 2.3 修改字段
```prisma
// 1. 修改字段类型或约束
model Document {
id String @id
title String @db.VarChar(500) // 修改长度
description String? @db.Text // 改为 Text 类型
@@schema("pkb_schema")
}
```
```bash
# 2. 生成迁移(注意:某些修改可能导致数据丢失)
npx prisma migrate dev --name update_document_fields
```
### 2.4 新增 Schema
```prisma
// 1. 在 datasource 中添加新 Schema
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = ["platform_schema", "aia_schema", "new_schema"] // 添加新 Schema
}
// 2. 创建使用新 Schema 的模型
model NewModule {
id String @id
name String
@@schema("new_schema")
}
```
---
## 3. 迁移文件管理
### 3.1 迁移文件结构
```
prisma/
├── schema.prisma # Schema 定义文件
├── migrations/
│ ├── 20251010075003_init/
│ │ └── migration.sql # 初始化迁移
│ ├── 20251012124747_add_batch/
│ │ └── migration.sql # 功能迁移
│ └── migration_lock.toml # 迁移锁文件
└── manual_sql_scripts/ # 手动 SQL仅用于特殊场景
└── *.sql
```
### 3.2 迁移文件命名规范
```bash
# 格式动词_对象_描述
npx prisma migrate dev --name add_user_phone_field
npx prisma migrate dev --name create_iit_schema_tables
npx prisma migrate dev --name update_document_status_enum
npx prisma migrate dev --name remove_deprecated_columns
```
### 3.3 迁移文件版本控制
```
✅ 必须提交的文件:
- prisma/schema.prisma
- prisma/migrations/*/migration.sql
- prisma/migrations/migration_lock.toml
❌ 不要提交的文件:
- 本地测试的临时迁移
```
---
## 4. 生产环境部署规范
### 4.1 部署前检查清单
```
┌─────────────────────────────────────────────────────────────────────┐
│ 📋 生产部署前检查清单 │
├─────────────────────────────────────────────────────────────────────┤
│ □ 本地开发环境测试通过 │
│ □ 迁移文件已提交到代码仓库 │
│ □ 已执行 npx prisma migrate status 确认待迁移列表 │
│ □ 已审查迁移 SQL确认无破坏性变更 │
│ □ 已备份生产数据库 │
│ □ 已准备回滚方案 │
│ □ 已通知相关人员 │
└─────────────────────────────────────────────────────────────────────┘
```
### 4.2 部署命令
```bash
# 1. 检查迁移状态
npx prisma migrate status
# 2. 执行迁移(仅应用未执行的迁移)
npx prisma migrate deploy
# 3. 生成 Prisma Client
npx prisma generate
```
### 4.3 SAE 环境部署
在 SAE 部署时Dockerfile 中应包含:
```dockerfile
# 构建阶段
RUN npx prisma generate
# 启动命令package.json 中配置)
# "start:prod": "npx prisma migrate deploy && node dist/main.js"
```
或在启动脚本中:
```bash
#!/bin/bash
# 应用迁移
npx prisma migrate deploy
# 启动应用
node dist/main.js
```
### 4.4 回滚方案
```bash
# 方案1从备份恢复推荐
cat backup_before_migration.sql | docker exec -i ai-clinical-postgres psql -U postgres -d ai_clinical_research
# 方案2手动回滚迁移需要准备回滚 SQL
# 在 migrations/ 目录下准备 rollback_xxx.sql
```
---
## 5. 多 Schema 架构规范
### 5.1 当前 Schema 列表
| Schema | 用途 | 表数量 | 管理方式 |
|--------|------|--------|----------|
| `platform_schema` | 平台基础设施用户、租户、pg-boss | 19 | Prisma + pg-boss |
| `aia_schema` | AI智能问答 | 3 | Prisma |
| `asl_schema` | 文献筛选 | 7 | Prisma |
| `pkb_schema` | 个人知识库 | 5 | Prisma |
| `dc_schema` | 数据清洗 | 6 | Prisma |
| `iit_schema` | IIT项目管理 | 5 | Prisma |
| `agent_schema` | Agent框架 | 6 | Prisma |
| `ekb_schema` | 企业知识库 | 3 | Prisma |
| `capability_schema` | 通用能力 | 2 | Prisma |
| `protocol_schema` | 方案设计 | 2 | Prisma |
| `rvw_schema` | 论文预审 | 1 | Prisma |
| `admin_schema` | 运营管理 | 2 | Prisma |
| `public` | 兼容旧数据 | 2 | Prisma |
### 5.2 新增 Schema 规范
```prisma
// 1. 在 datasource 中声明
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
schemas = [
"platform_schema",
"aia_schema",
// ... 现有 schemas
"new_module_schema" // 新增
]
}
// 2. 在模型中使用
model NewModuleTable {
id String @id @default(uuid())
name String
@@map("new_module_tables")
@@schema("new_module_schema")
}
```
### 5.3 命名规范
| 类型 | 格式 | 示例 |
|------|------|------|
| Schema | `{module}_schema` | `iit_schema`, `asl_schema` |
| 表名 | `{module_prefix}_{entity_name}` | `dc_templates`, `asl_literatures` |
| 字段名 | `snake_case` | `created_at`, `user_id` |
| 索引名 | `idx_{table}_{column}` | `idx_users_email` |
---
## 6. 特殊场景处理
### 6.1 pg-boss 表(自动管理)
pg-boss 会自动创建和管理以下表,**不需要**在 Prisma Schema 中定义:
| 表名 | 用途 |
|------|------|
| `platform_schema.job` | 任务队列 |
| `platform_schema.job_common` | 任务通用信息 |
| `platform_schema.queue` | 队列定义 |
| `platform_schema.schedule` | 定时任务 |
| `platform_schema.subscription` | 订阅信息 |
| `platform_schema.version` | 版本信息 |
### 6.2 pgvector 字段
```prisma
// pgvector 类型使用 Unsupported
model EkbChunk {
id String @id
content String
embedding Unsupported("vector")? // 向量字段
@@schema("ekb_schema")
}
```
操作 vector 字段时使用原生 SQL
```typescript
// 插入向量
await prisma.$executeRaw`
UPDATE ekb_schema.ekb_chunk
SET embedding = ${embedding}::vector
WHERE id = ${id}
`
// 相似度查询
const results = await prisma.$queryRaw`
SELECT id, content, 1 - (embedding <=> ${queryVector}::vector) as similarity
FROM ekb_schema.ekb_chunk
ORDER BY embedding <=> ${queryVector}::vector
LIMIT 10
`
```
### 6.3 从数据库同步 Schema紧急情况
仅在 Schema 与数据库严重不一致时使用:
```bash
# 1. 备份当前 Schema
cp prisma/schema.prisma prisma/schema.prisma.backup
# 2. 从数据库拉取
npx prisma db pull
# 3. 标记所有现有迁移为已应用
npx prisma migrate resolve --applied <migration_name>
# 4. 验证
npx prisma migrate status
```
---
## 7. 备份规范
### 7.1 备份时机
| 时机 | 是否必须 | 备份方式 |
|------|----------|----------|
| 执行 `prisma migrate deploy` 前 | ✅ 必须 | 全量备份 |
| 重大功能发布前 | ✅ 必须 | 全量备份 |
| 每日自动备份 | ✅ 推荐 | 增量/全量 |
| 数据导入前 | ✅ 必须 | 全量备份 |
### 7.2 备份命令
```bash
# 本地 Docker 备份
docker exec ai-clinical-postgres pg_dump \
-U postgres \
-d ai_clinical_research \
--format=plain \
--no-owner \
--no-acl \
> backup_$(date +%Y%m%d_%H%M%S).sql
# RDS 备份(需要开启外网访问)
PGPASSWORD='xxx' pg_dump \
-h pgm-xxx.pg.rds.aliyuncs.com \
-p 5432 \
-U airesearch \
-d ai_clinical_research_test \
--format=plain \
--no-owner \
> rds_backup_$(date +%Y%m%d_%H%M%S).sql
```
---
## 8. 常见问题
### 8.1 迁移冲突
```bash
# 问题:多人开发时迁移文件冲突
# 解决:
1. git pull 获取最新代码
2. npx prisma migrate status 查看状态
3. 如有冲突,手动合并迁移文件或重新生成
```
### 8.2 迁移失败回滚
```bash
# 问题migrate deploy 失败
# 解决:
1. 从备份恢复数据库
2. 修复 schema.prisma
3. 重新生成迁移
4. 再次尝试部署
```
### 8.3 Schema 与数据库不一致
```bash
# 检查差异
npx prisma migrate diff \
--from-schema-datasource prisma/schema.prisma \
--to-schema-datamodel prisma/schema.prisma
# 如果需要重新同步
npx prisma db pull # 从数据库拉取
# 或
npx prisma migrate dev # 从 Schema 推送
```
---
## 9. 检查清单
### 9.1 每次变更前
- [ ] 已从主分支更新代码
- [ ] 已运行 `npx prisma migrate status`
- [ ] 已备份本地数据库(重要数据)
### 9.2 每次变更后
- [ ] 迁移文件已生成
- [ ] 本地功能测试通过
- [ ] 已检查生成的迁移 SQL
- [ ] 已提交 schema.prisma 和迁移文件
### 9.3 生产部署时
- [ ] 已备份生产数据库
- [ ] 已在测试环境验证迁移
- [ ] 已准备回滚方案
- [ ] 已执行 `npx prisma migrate deploy`
- [ ] 已验证应用正常运行
---
## 附录:历史事故
### 案例12026-01-11 数据库重置事故
**原因**:使用 `prisma db push --force-reset`
**影响**pg-boss 函数丢失,用户数据丢失
**教训**:永远不要使用 `--force-reset`,操作前必须备份
### 案例2手工 SQL 导致 Schema 不一致
**原因**:直接执行 `ALTER TABLE` 添加字段
**影响**Prisma Schema 与数据库不一致,后续迁移失败
**教训**:所有变更必须通过 Prisma Schema
---
> 📌 **记住**Prisma Schema 是唯一真相来源Single Source of Truth
> 所有数据库结构变更必须先修改 Schema再通过迁移应用到数据库