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
15 KiB
15 KiB
数据库开发规范
版本: 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 - 已验证应用正常运行
附录:历史事故
案例1:2026-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,再通过迁移应用到数据库