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

15 KiB
Raw Blame History

数据库开发规范

版本: 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 新增表

// 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
}
# 2. 生成迁移
npx prisma migrate dev --name add_new_feature_table

# 3. 检查生成的 SQL
cat prisma/migrations/xxx_add_new_feature_table/migration.sql

2.2 新增字段

// 1. 在模型中添加字段
model User {
  id        String   @id
  email     String
  phone     String?  // 新增字段,可为空
  createdAt DateTime @default(now())
  
  @@schema("platform_schema")
}
# 2. 生成迁移
npx prisma migrate dev --name add_user_phone_field

2.3 修改字段

// 1. 修改字段类型或约束
model Document {
  id          String  @id
  title       String  @db.VarChar(500)  // 修改长度
  description String? @db.Text          // 改为 Text 类型
  
  @@schema("pkb_schema")
}
# 2. 生成迁移(注意:某些修改可能导致数据丢失)
npx prisma migrate dev --name update_document_fields

2.4 新增 Schema

// 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 迁移文件命名规范

# 格式动词_对象_描述
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 部署命令

# 1. 检查迁移状态
npx prisma migrate status

# 2. 执行迁移(仅应用未执行的迁移)
npx prisma migrate deploy

# 3. 生成 Prisma Client
npx prisma generate

4.3 SAE 环境部署

在 SAE 部署时Dockerfile 中应包含:

# 构建阶段
RUN npx prisma generate

# 启动命令package.json 中配置)
# "start:prod": "npx prisma migrate deploy && node dist/main.js"

或在启动脚本中:

#!/bin/bash
# 应用迁移
npx prisma migrate deploy

# 启动应用
node dist/main.js

4.4 回滚方案

# 方案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 规范

// 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 字段

// pgvector 类型使用 Unsupported
model EkbChunk {
  id        String                  @id
  content   String
  embedding Unsupported("vector")?  // 向量字段
  
  @@schema("ekb_schema")
}

操作 vector 字段时使用原生 SQL

// 插入向量
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 与数据库严重不一致时使用:

# 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 备份命令

# 本地 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 迁移冲突

# 问题:多人开发时迁移文件冲突
# 解决:
1. git pull 获取最新代码
2. npx prisma migrate status 查看状态
3. 如有冲突,手动合并迁移文件或重新生成

8.2 迁移失败回滚

# 问题migrate deploy 失败
# 解决:
1. 从备份恢复数据库
2. 修复 schema.prisma
3. 重新生成迁移
4. 再次尝试部署

8.3 Schema 与数据库不一致

# 检查差异
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再通过迁移应用到数据库