From c56585f3434a3ee587fc81d568ce31216f4bc9ff Mon Sep 17 00:00:00 2001 From: sylarchen1389 Date: Sun, 7 Dec 2025 12:40:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=A1=A5=E5=85=85Alembic=E6=8C=87?= =?UTF-8?q?=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ALEMBIC_GUIDE.md | 451 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 451 insertions(+) create mode 100644 docs/ALEMBIC_GUIDE.md diff --git a/docs/ALEMBIC_GUIDE.md b/docs/ALEMBIC_GUIDE.md new file mode 100644 index 0000000000..a427756af9 --- /dev/null +++ b/docs/ALEMBIC_GUIDE.md @@ -0,0 +1,451 @@ +# Alembic 使用攻略 - Open WebUI + +## 🚀 快速开始 + +### 当前项目配置 +- **自动迁移**: 应用启动时自动执行 `alembic upgrade head` +- **位置**: `backend/open_webui/config.py:53-70` +- **结论**: 拉取代码后重启应用即可,无需手动执行迁移 + +### 工具脚本 +```bash +./scripts/migrate.sh current # 查看当前版本 +./scripts/migrate.sh upgrade # 手动升级 +./scripts/check-status.sh # 检查数据库与代码一致性 +``` + +--- + +## 📝 开发协作流程 + +### 场景1: 添加新表 + +```bash +# 1. 创建迁移脚本 +cd backend/open_webui +python -m alembic revision -m "add_user_credits_table" + +# 2. 编辑生成的文件 migrations/versions/xxxx_add_user_credits_table.py +``` + +```python +def upgrade(): + op.create_table( + 'user_credits', + sa.Column('id', sa.String(), nullable=False), + sa.Column('user_id', sa.String(), nullable=False), + sa.Column('credits', sa.NUMERIC(20, 6), server_default='0', nullable=False), + sa.Column('created_at', sa.BigInteger(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_index('idx_user_credits_user_id', 'user_credits', ['user_id']) + +def downgrade(): + op.drop_index('idx_user_credits_user_id', 'user_credits') + op.drop_table('user_credits') +``` + +```bash +# 3. 测试迁移 +source venv/bin/activate +cd open_webui +python -m alembic upgrade head # 升级 +python -m alembic downgrade -1 # 降级测试 +python -m alembic upgrade head # 重新升级 + +# 4. 验证 +python -c " +from open_webui.internal.db import get_db +from sqlalchemy import inspect +with get_db() as db: + print(inspect(db.bind).get_table_names()) +" + +# 5. 提交 +git add migrations/versions/xxxx_add_user_credits_table.py +git add open_webui/models/credits.py +git commit -m "feat: add user credits system" +git push +``` + +### 场景2: 修改现有表 + +```bash +# 1. 创建迁移 +python -m alembic revision -m "add_email_verified_to_user" + +# 2. 编辑迁移文件 +``` + +```python +def upgrade(): + # 添加字段 + op.add_column('user', sa.Column('email_verified', sa.Boolean(), + server_default='false', nullable=False)) + + # 添加索引 + op.create_index('idx_user_email_verified', 'user', ['email_verified']) + +def downgrade(): + op.drop_index('idx_user_email_verified', 'user') + op.drop_column('user', 'email_verified') +``` + +```bash +# 3. 测试并提交(同场景1步骤3-5) +``` + +### 场景3: 数据迁移 + +```python +from sqlalchemy import text + +def upgrade(): + connection = op.get_bind() + + # 1. 添加新字段 + op.add_column('user', sa.Column('full_name', sa.String(), nullable=True)) + + # 2. 迁移数据 + connection.execute(text(""" + UPDATE user + SET full_name = name + WHERE full_name IS NULL + """)) + + # 3. 设置为NOT NULL + op.alter_column('user', 'full_name', nullable=False) + +def downgrade(): + op.drop_column('user', 'full_name') +``` + +### 场景4: 多人协作冲突 + +**问题**: 两个分支同时创建迁移,产生多个head + +```bash +# 1. 发现问题 +python -m alembic heads +# 输出: abc123 (head), def456 (head) ← 两个头部 + +# 2. 合并迁移 +python -m alembic merge -m "merge_feature_branches" heads + +# 3. 编辑生成的合并迁移 +# migrations/versions/xxx_merge_feature_branches.py +# down_revision = ('abc123', 'def456') # 已自动填充 + +# 4. 应用合并 +python -m alembic upgrade head + +# 5. 提交 +git add migrations/versions/xxx_merge_feature_branches.py +git commit -m "chore: merge migration branches" +``` + +--- + +## 🏭 生产环境迁移 + +### 方式1: 自动迁移(推荐) + +```bash +# Docker 环境 +git pull +docker-compose restart +# ✅ 应用启动时自动执行迁移 + +# Systemd 环境 +git pull +systemctl restart open-webui +# ✅ 应用启动时自动执行迁移 + +# 验证 +./scripts/check-status.sh +``` + +**优点**: 零停机、自动化、幂等性 +**适用**: 小型迁移、添加字段、创建索引 + +### 方式2: 手动迁移(安全) + +```bash +# 1. 备份数据库(PostgreSQL) +pg_dump -U user -d openwebui_prod > backup_$(date +%Y%m%d_%H%M%S).sql + +# 2. 记录当前版本 +cd backend/open_webui +python -m alembic current > migration_before.txt + +# 3. 拉取代码 +git pull + +# 4. 查看待执行的迁移 +python -m alembic history | grep -A5 "$(cat migration_before.txt | awk '{print $1}')" + +# 5. 手动执行迁移 +python -m alembic upgrade head + +# 6. 验证 +python -m alembic current > migration_after.txt +diff migration_before.txt migration_after.txt + +# 7. 重启应用 +systemctl restart open-webui + +# 8. 功能验证 +curl http://localhost:8080/health +``` + +**优点**: 可控、可验证、可回滚 +**适用**: 大型迁移、数据迁移、高风险变更 + +### 方式3: 蓝绿部署(零停机) + +```bash +# 1. 部署新版本到绿环境(不启动) +git clone /app/open-webui /app/open-webui-green +cd /app/open-webui-green +git pull + +# 2. 在绿环境执行迁移 +cd backend/open_webui +python -m alembic upgrade head + +# 3. 启动绿环境(连接同一数据库) +systemctl start open-webui-green + +# 4. 切换流量(Nginx/负载均衡) +# 从 localhost:8080 → localhost:8081 + +# 5. 停止蓝环境 +systemctl stop open-webui + +# 6. 验证后删除蓝环境 +rm -rf /app/open-webui +mv /app/open-webui-green /app/open-webui +``` + +--- + +## 🔧 常用命令速查 + +### 查看状态 +```bash +python -m alembic current # 当前版本 +python -m alembic heads # 最新版本 +python -m alembic history # 历史记录 +python -m alembic branches # 分支情况 +``` + +### 执行迁移 +```bash +python -m alembic upgrade head # 升级到最新 +python -m alembic upgrade +1 # 升级1个版本 +python -m alembic upgrade abc123 # 升级到指定版本 +python -m alembic downgrade -1 # 降级1个版本 +python -m alembic downgrade abc123 # 降级到指定版本 +``` + +### 创建迁移 +```bash +python -m alembic revision -m "description" # 创建空迁移 +python -m alembic merge -m "merge branches" heads # 合并分支 +``` + +--- + +## ⚠️ 注意事项 + +### 1. 禁止使用 autogenerate +```bash +# ❌ 不要用(循环依赖问题) +python -m alembic revision --autogenerate -m "auto" + +# ✅ 手动编写 +python -m alembic revision -m "add_feature" +# 然后手动编写 upgrade/downgrade 函数 +``` + +### 2. 数据库类型(PostgreSQL) + +```python +# 使用 PostgreSQL 特定类型 +from sqlalchemy.dialects import postgresql + +def upgrade(): + op.add_column('user', + sa.Column('balance', postgresql.NUMERIC(20, 6), + server_default='0', nullable=False)) +``` + +### 3. 大表索引创建 + +```python +# PostgreSQL - 在线创建索引 +op.create_index( + 'idx_large_table_field', + 'large_table', + ['field'], + postgresql_concurrently=True # 不锁表 +) + +# 注意: CONCURRENTLY 需要在事务外执行 +# 在迁移文件顶部添加: +# revision = 'xxx' +# down_revision = 'yyy' +# branch_labels = None +# depends_on = None +# +# # 禁用事务 +# def upgrade(): +# op.execute('COMMIT') +# ... +``` + +### 4. 必须编写 downgrade + +```python +# ❌ 错误 +def downgrade(): + pass + +# ✅ 正确 +def downgrade(): + op.drop_index('idx_user_balance') + op.drop_column('user', 'balance') +``` + +--- + +## 🚨 故障处理 + +### 迁移失败恢复 + +```bash +# 1. 查看当前状态 +python -m alembic current + +# 2. 检查数据库是否处于中间状态 +psql -U user -d dbname +\dt # 查看表 +# 手动删除失败迁移创建的表/字段 + +# 3. 标记为指定版本(谨慎使用) +python -m alembic stamp + +# 4. 重新执行 +python -m alembic upgrade head +``` + +### 回滚到指定版本 + +```bash +# 1. 查看历史 +python -m alembic history + +# 2. 回滚 +python -m alembic downgrade + +# 3. 重启应用 +systemctl restart open-webui +``` + +### 强制重新初始化(危险) + +```bash +# ⚠️ 会丢失所有数据 +# 1. 删除 alembic_version 表 +psql -U user -d dbname -c "DROP TABLE alembic_version;" + +# 2. 删除所有业务表 +psql -U user -d dbname -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;" + +# 3. 重新执行所有迁移 +python -m alembic upgrade head +``` + +--- + +## ✅ 最佳实践检查清单 + +### 开发阶段 +- [ ] 修改模型后立即创建迁移脚本 +- [ ] 迁移脚本命名清晰(描述变更内容) +- [ ] 编写完整的 upgrade 和 downgrade 函数 +- [ ] 使用 PostgreSQL 特定类型(NUMERIC, JSONB 等) +- [ ] 测试升级和降级流程 +- [ ] Code Review 检查迁移逻辑 +- [ ] 提交迁移脚本到 Git + +### 部署阶段 +- [ ] 备份生产数据库 +- [ ] 记录当前迁移版本 +- [ ] 查看待执行的迁移内容 +- [ ] 评估迁移风险(大表、数据迁移) +- [ ] 选择合适的迁移方式(自动/手动) +- [ ] 执行迁移 +- [ ] 验证迁移版本 +- [ ] 重启应用 +- [ ] 功能验证 +- [ ] 监控应用日志 + +--- + +## 📊 迁移决策树 + +``` +新功能需要数据库变更 + ↓ +修改 models/*.py + ↓ +创建迁移脚本 (alembic revision -m "xxx") + ↓ +编写 upgrade/downgrade 函数 + ↓ +┌─────────────────────────────┐ +│ 影响是否 > 1000万行数据? │ +└─────────┬───────────────────┘ + │ + ┌─────┴─────┐ + NO YES + │ │ + │ 使用分批迁移/在线DDL + ↓ ↓ +测试升降级 准备回滚方案 + │ │ + └─────┬─────┘ + ↓ +提交代码 (git commit) + ↓ + ┌───────────┐ + │ 生产部署 │ + └─────┬─────┘ + │ + ┌─────┴─────┐ + 风险评估 + │ +┌───┴───┐ +低 高 +│ │ +│ 手动迁移 +│ + 备份 +自动 + 蓝绿 +迁移 +``` + +--- + +## 📚 参考资源 + +- **项目文档**: `docs/DATABASE_CONSISTENCY_GUIDE.md` - 完整指南 +- **迁移工具**: `scripts/migrate.sh` - 便捷脚本 +- **状态检查**: `scripts/check-status.sh` - 一致性验证 +- **Alembic 官方文档**: https://alembic.sqlalchemy.org/ + +--- + +**版本**: v1.0 +**更新**: 2025-12-06 +**适用**: Open WebUI Next