geo/.qoder/repowiki/zh/content/数据库设计/数据库迁移.md

319 lines
14 KiB
Markdown
Raw Permalink 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.

# 数据库迁移
<cite>
**本文引用的文件**
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py)
- [backend/alembic/env.py](file://backend/alembic/env.py)
- [backend/alembic.ini](file://backend/alembic.ini)
- [backend/alembic/script.py.mako](file://backend/alembic/script.py.mako)
- [backend/app/database.py](file://backend/app/database.py)
- [backend/app/models/__init__.py](file://backend/app/models/__init__.py)
- [backend/app/models/user.py](file://backend/app/models/user.py)
- [backend/app/models/query.py](file://backend/app/models/query.py)
- [backend/app/models/citation_record.py](file://backend/app/models/citation_record.py)
- [backend/app/models/query_task.py](file://backend/app/models/query_task.py)
- [backend/app/models/subscription.py](file://backend/app/models/subscription.py)
- [backend/app/config.py](file://backend/app/config.py)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向GEO项目的数据库迁移与版本管理系统性说明基于Alembic的迁移框架配置与使用方式覆盖迁移脚本生成、版本管理、数据库升级策略、初始迁移实现含表创建、索引与约束、迁移命令upgrade、downgrade、autogenerate以及生产环境最佳实践与风险控制。读者无需深入Python或SQLAlchemy即可理解并安全地执行迁移。
## 项目结构
GEO后端采用异步SQLAlchemy与Alembic进行数据库迁移管理迁移相关代码集中在backend/alembic目录中并通过env.py与应用模型models建立连接。数据库连接由应用配置提供迁移脚本位于versions子目录中按版本顺序命名。
```mermaid
graph TB
subgraph "迁移配置"
A["alembic.ini<br/>脚本位置、日志、URL等"]
B["env.py<br/>在线/离线迁移入口"]
C["script.py.mako<br/>迁移模板"]
end
subgraph "模型定义"
D["models/__init__.py<br/>导出所有模型"]
E["models/user.py"]
F["models/query.py"]
G["models/citation_record.py"]
H["models/query_task.py"]
I["models/subscription.py"]
end
subgraph "数据库"
J["PostgreSQL 实例"]
end
A --> B
B --> D
D --> E
D --> F
D --> G
D --> H
D --> I
B --> J
```
**图表来源**
- [backend/alembic.ini:1-150](file://backend/alembic.ini#L1-L150)
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/alembic/script.py.mako:1-29](file://backend/alembic/script.py.mako#L1-L29)
- [backend/app/models/__init__.py:1-14](file://backend/app/models/__init__.py#L1-L14)
- [backend/app/models/user.py:1-41](file://backend/app/models/user.py#L1-L41)
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
- [backend/app/models/citation_record.py:1-42](file://backend/app/models/citation_record.py#L1-L42)
- [backend/app/models/query_task.py:1-39](file://backend/app/models/query_task.py#L1-L39)
- [backend/app/models/subscription.py:1-37](file://backend/app/models/subscription.py#L1-L37)
**章节来源**
- [backend/alembic.ini:1-150](file://backend/alembic.ini#L1-L150)
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/app/models/__init__.py:1-14](file://backend/app/models/__init__.py#L1-L14)
## 核心组件
- 迁移配置与入口
- alembic.ini定义脚本位置、日志级别、数据库URL等全局设置。
- env.py根据运行模式在线/离线)加载目标元数据并执行迁移。
- script.py.mako迁移脚本模板定义upgrade/downgrade骨架。
- 模型与元数据
- models/__init__.py聚合导出所有ORM模型供Alembic扫描。
- 各模型文件:定义表结构、字段类型、索引与外键关系。
- 数据库引擎
- app/database.py创建异步引擎与Base为迁移提供元数据基础。
- app/config.py提供DATABASE_URL被env.py与alembic.ini共同使用。
**章节来源**
- [backend/alembic.ini:1-150](file://backend/alembic.ini#L1-L150)
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/alembic/script.py.mako:1-29](file://backend/alembic/script.py.mako#L1-L29)
- [backend/app/models/__init__.py:1-14](file://backend/app/models/__init__.py#L1-L14)
- [backend/app/models/user.py:1-41](file://backend/app/models/user.py#L1-L41)
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
- [backend/app/models/citation_record.py:1-42](file://backend/app/models/citation_record.py#L1-L42)
- [backend/app/models/query_task.py:1-39](file://backend/app/models/query_task.py#L1-L39)
- [backend/app/models/subscription.py:1-37](file://backend/app/models/subscription.py#L1-L37)
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
## 架构总览
下图展示从命令到数据库的迁移执行链路,包括在线与离线两种模式,以及模型元数据对迁移的影响。
```mermaid
sequenceDiagram
participant CLI as "命令行"
participant Alembic as "Alembic CLI"
participant Env as "env.py"
participant DB as "PostgreSQL"
CLI->>Alembic : 执行迁移命令
Alembic->>Env : 加载配置与元数据
Env->>Env : 判断在线/离线模式
alt 在线模式
Env->>DB : 异步连接并执行事务
else 离线模式
Env->>DB : 使用URL直接执行DDL
end
Env-->>Alembic : 返回迁移结果
Alembic-->>CLI : 输出状态与日志
```
**图表来源**
- [backend/alembic/env.py:33-89](file://backend/alembic/env.py#L33-L89)
- [backend/alembic.ini:86-89](file://backend/alembic.ini#L86-L89)
## 详细组件分析
### 初始迁移脚本488d0bd5ab01
该脚本实现首次数据库初始化,包含以下要点:
- 表创建
- users用户主表包含唯一邮箱、计划等级、配额、激活状态等字段。
- queries查询任务表关联users包含关键词、品牌、平台列表、频率、状态及时间戳。
- citation_records引用记录表关联queries包含平台、是否引用、竞品品牌、原始响应等。
- query_tasks查询任务执行表关联queries包含状态、错误信息与调度/开始/完成时间。
- subscriptions订阅表关联users包含计划、状态、起止日期、金额与支付信息。
- 索引建立
- queries按user_id、status、next_query_at建立索引。
- citation_records按query_id、queried_at、platform建立索引。
- query_tasks按status建立索引。
- 约束与默认值
- 外键约束:各子表均对父表执行级联删除。
- 默认值广泛使用服务器默认值如NOW()、JSONB空数组、字符串默认值
- 回滚策略
- downgrade按逆序删除表与索引确保幂等与可恢复。
```mermaid
flowchart TD
Start(["执行初始迁移"]) --> CreateUsers["创建 users 表"]
CreateUsers --> CreateQueries["创建 queries 表<br/>建立索引"]
CreateQueries --> CreateRecords["创建 citation_records 表<br/>建立索引"]
CreateRecords --> CreateTasks["创建 query_tasks 表<br/>建立索引"]
CreateTasks --> CreateSubs["创建 subscriptions 表"]
CreateSubs --> End(["完成"])
```
**图表来源**
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:21-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L21-L128)
**章节来源**
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L1-L128)
### 迁移环境与元数据
- 元数据来源
- env.py通过app.database.Base.metadata提供目标元数据确保Alembic能识别应用模型的变更。
- models/__init__.py统一导出所有模型避免遗漏。
- 在线/离线模式
- 在线模式:使用异步引擎连接数据库,适合生产与容器环境。
- 离线模式直接使用URL执行DDL便于测试与快速验证。
- 配置来源
- DATABASE_URL来自app/config.py同时在alembic.ini中也有默认示例URL。
```mermaid
graph LR
A["env.py"] --> B["Base.metadata"]
B --> C["models/*"]
A --> D["在线/离线执行器"]
D --> E["PostgreSQL"]
```
**图表来源**
- [backend/alembic/env.py:10-25](file://backend/alembic/env.py#L10-L25)
- [backend/app/models/__init__.py:1-14](file://backend/app/models/__init__.py#L1-L14)
- [backend/app/database.py](file://backend/app/database.py#L20)
- [backend/app/config.py](file://backend/app/config.py#L7)
**章节来源**
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/app/models/__init__.py:1-14](file://backend/app/models/__init__.py#L1-L14)
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
### 迁移命令与工作流
- 常用命令
- 升级:将数据库迁移到最新版本。
- 降级:将数据库回退到指定版本。
- 自动化生成:基于模型变更自动生成迁移脚本。
- 工作流建议
- 开发阶段先在本地dev环境验证再合并到测试环境。
- 测试阶段:在隔离数据库上执行,验证数据完整性与索引有效性。
- 生产阶段:严格遵循“只读优先”原则,先备份,再执行,最后验证。
```mermaid
flowchart TD
Dev["开发环境"] --> Test["测试环境"]
Test --> Prod["生产环境"]
Dev --> |dry-run/验证| Test
Test --> |备份/演练| Prod
```
[本节为通用流程说明,不直接分析具体文件,故无“章节来源”]
### 数据保护、回滚与版本控制
- 数据保护
- 在生产环境执行前务必备份数据库。
- 对大表操作(如重建索引)选择维护窗口,避免高峰时段。
- 回滚机制
- 初始迁移提供完整的downgrade路径确保可逆。
- 建议每次迁移仅包含单一逻辑变更,降低回滚复杂度。
- 版本控制
- 迁移脚本以版本号命名,保持顺序与可追溯性。
- 将迁移脚本纳入版本控制系统,配合提交信息描述变更意图。
**章节来源**
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:114-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L114-L128)
### 生产环境最佳实践与风险控制
- 风险控制
- 限制迁移窗口,避免业务高峰期。
- 使用只读副本或独立测试库先行验证。
- 对DDL操作进行分批执行逐步替换索引与约束。
- 可观测性
- 记录迁移日志,监控执行时长与失败原因。
- 在应用侧增加迁移状态检查,防止未完成迁移导致的数据不一致。
- 安全与合规
- 严格管理DATABASE_URL与访问权限。
- 对敏感字段(如密码哈希)迁移需遵循最小暴露原则。
**章节来源**
- [backend/alembic.ini:115-150](file://backend/alembic.ini#L115-L150)
- [backend/alembic/env.py:33-89](file://backend/alembic/env.py#L33-L89)
## 依赖分析
- 组件耦合
- env.py依赖app/config.py提供的DATABASE_URL与app/database.py的Base元数据。
- models/__init__.py集中导出所有模型提升扫描效率与一致性。
- 外部依赖
- PostgreSQL作为目标数据库UUID、JSONB、时间戳等类型在迁移脚本中被广泛使用。
- 潜在问题
- 若models/__init__.py遗漏导出可能导致autogenerate无法识别新模型。
- 在线迁移依赖异步引擎,需确保网络与连接池配置正确。
```mermaid
graph TB
Env["env.py"] --> Cfg["app/config.py"]
Env --> DB["app/database.py"]
DB --> Meta["Base.metadata"]
Meta --> Models["models/*"]
```
**图表来源**
- [backend/alembic/env.py:10-25](file://backend/alembic/env.py#L10-L25)
- [backend/app/config.py](file://backend/app/config.py#L7)
- [backend/app/database.py](file://backend/app/database.py#L20)
- [backend/app/models/__init__.py:1-14](file://backend/app/models/__init__.py#L1-L14)
**章节来源**
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/models/__init__.py:1-14](file://backend/app/models/__init__.py#L1-L14)
## 性能考虑
- 索引设计
- 初始迁移已为高频查询字段建立索引,有助于提升查询性能。
- 对于大表,建议在维护窗口内重建索引,避免阻塞。
- 迁移窗口
- 将DDL密集型操作安排在低峰时段减少对线上服务的影响。
- 幂等性
- 迁移脚本应具备幂等特性,避免重复执行造成资源浪费。
**章节来源**
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:57-94](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L57-L94)
## 故障排查指南
- 常见问题
- 迁移失败检查DATABASE_URL是否正确确认数据库可达。
- 模型未识别确保models/__init__.py导出了新增模型。
- 在线/离线模式混淆:确认运行环境与配置文件一致。
- 排查步骤
- 查看日志调整alembic.ini中的日志级别以获取更详细输出。
- 回滚验证使用downgrade验证回滚路径是否完整。
- 数据核对:迁移完成后执行简单查询,核对关键索引与约束是否生效。
**章节来源**
- [backend/alembic.ini:115-150](file://backend/alembic.ini#L115-L150)
- [backend/alembic/env.py:33-89](file://backend/alembic/env.py#L33-L89)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:114-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L114-L128)
## 结论
GEO项目已建立完善的Alembic迁移体系清晰的配置、可靠的元数据扫描、完备的初始迁移脚本与回滚路径。遵循本文的命令使用方法、最佳实践与风险控制措施可在保障数据安全的前提下高效推进数据库演进。
## 附录
- 迁移命令速查
- 升级到最新alembic upgrade head
- 降级到上一版本alembic downgrade -1
- 降级到指定版本alembic downgrade <版本号>
- 自动生成迁移alembic revision --autogenerate -m "<描述>"
- 关键文件定位
- 配置backend/alembic.ini
- 环境backend/alembic/env.py
- 模板backend/alembic/script.py.mako
- 初始迁移backend/alembic/versions/488d0bd5ab01_initial_migration.py
- 模型聚合backend/app/models/__init__.py
- 数据库配置backend/app/config.py