14 KiB
14 KiB
数据库迁移
**本文引用的文件** - [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)目录
简介
本文件面向GEO项目的数据库迁移与版本管理,系统性说明基于Alembic的迁移框架配置与使用方式,覆盖迁移脚本生成、版本管理、数据库升级策略、初始迁移实现(含表创建、索引与约束)、迁移命令(upgrade、downgrade、autogenerate)以及生产环境最佳实践与风险控制。读者无需深入Python或SQLAlchemy即可理解并安全地执行迁移。
项目结构
GEO后端采用异步SQLAlchemy与Alembic进行数据库迁移管理,迁移相关代码集中在backend/alembic目录中,并通过env.py与应用模型(models)建立连接。数据库连接由应用配置提供,迁移脚本位于versions子目录中,按版本顺序命名。
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
- backend/alembic/env.py:1-89
- backend/alembic/script.py.mako:1-29
- backend/app/models/init.py:1-14
- backend/app/models/user.py:1-41
- backend/app/models/query.py:1-55
- backend/app/models/citation_record.py:1-42
- backend/app/models/query_task.py:1-39
- backend/app/models/subscription.py:1-37
章节来源
核心组件
- 迁移配置与入口
- 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
- backend/alembic/env.py:1-89
- backend/alembic/script.py.mako:1-29
- backend/app/models/init.py:1-14
- backend/app/models/user.py:1-41
- backend/app/models/query.py:1-55
- backend/app/models/citation_record.py:1-42
- backend/app/models/query_task.py:1-39
- backend/app/models/subscription.py:1-37
- backend/app/database.py:1-29
- backend/app/config.py:1-17
架构总览
下图展示从命令到数据库的迁移执行链路,包括在线与离线两种模式,以及模型元数据对迁移的影响。
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 : 输出状态与日志
图表来源
详细组件分析
初始迁移脚本(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按逆序删除表与索引,确保幂等与可恢复。
flowchart TD
Start(["执行初始迁移"]) --> CreateUsers["创建 users 表"]
CreateUsers --> CreateQueries["创建 queries 表<br/>建立索引"]
CreateQueries --> CreateRecords["创建 citation_records 表<br/>建立索引"]
CreateRecords --> CreateTasks["创建 query_tasks 表<br/>建立索引"]
CreateTasks --> CreateSubs["创建 subscriptions 表"]
CreateSubs --> End(["完成"])
图表来源
章节来源
迁移环境与元数据
- 元数据来源
- env.py通过app.database.Base.metadata提供目标元数据,确保Alembic能识别应用模型的变更。
- models/init.py统一导出所有模型,避免遗漏。
- 在线/离线模式
- 在线模式:使用异步引擎连接数据库,适合生产与容器环境。
- 离线模式:直接使用URL执行DDL,便于测试与快速验证。
- 配置来源
- DATABASE_URL来自app/config.py,同时在alembic.ini中也有默认示例URL。
graph LR
A["env.py"] --> B["Base.metadata"]
B --> C["models/*"]
A --> D["在线/离线执行器"]
D --> E["PostgreSQL"]
图表来源
- backend/alembic/env.py:10-25
- backend/app/models/init.py:1-14
- backend/app/database.py
- backend/app/config.py
章节来源
- backend/alembic/env.py:1-89
- backend/app/models/init.py:1-14
- backend/app/database.py:1-29
- backend/app/config.py:1-17
迁移命令与工作流
- 常用命令
- 升级:将数据库迁移到最新版本。
- 降级:将数据库回退到指定版本。
- 自动化生成:基于模型变更自动生成迁移脚本。
- 工作流建议
- 开发阶段:先在本地dev环境验证,再合并到测试环境。
- 测试阶段:在隔离数据库上执行,验证数据完整性与索引有效性。
- 生产阶段:严格遵循“只读优先”原则,先备份,再执行,最后验证。
flowchart TD
Dev["开发环境"] --> Test["测试环境"]
Test --> Prod["生产环境"]
Dev --> |dry-run/验证| Test
Test --> |备份/演练| Prod
[本节为通用流程说明,不直接分析具体文件,故无“章节来源”]
数据保护、回滚与版本控制
- 数据保护
- 在生产环境执行前务必备份数据库。
- 对大表操作(如重建索引)选择维护窗口,避免高峰时段。
- 回滚机制
- 初始迁移提供完整的downgrade路径,确保可逆。
- 建议每次迁移仅包含单一逻辑变更,降低回滚复杂度。
- 版本控制
- 迁移脚本以版本号命名,保持顺序与可追溯性。
- 将迁移脚本纳入版本控制系统,配合提交信息描述变更意图。
章节来源
生产环境最佳实践与风险控制
- 风险控制
- 限制迁移窗口,避免业务高峰期。
- 使用只读副本或独立测试库先行验证。
- 对DDL操作进行分批执行,逐步替换索引与约束。
- 可观测性
- 记录迁移日志,监控执行时长与失败原因。
- 在应用侧增加迁移状态检查,防止未完成迁移导致的数据不一致。
- 安全与合规
- 严格管理DATABASE_URL与访问权限。
- 对敏感字段(如密码哈希)迁移需遵循最小暴露原则。
章节来源
依赖分析
- 组件耦合
- env.py依赖app/config.py提供的DATABASE_URL与app/database.py的Base元数据。
- models/init.py集中导出所有模型,提升扫描效率与一致性。
- 外部依赖
- PostgreSQL作为目标数据库,UUID、JSONB、时间戳等类型在迁移脚本中被广泛使用。
- 潜在问题
- 若models/init.py遗漏导出,可能导致autogenerate无法识别新模型。
- 在线迁移依赖异步引擎,需确保网络与连接池配置正确。
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
- backend/app/config.py
- backend/app/database.py
- backend/app/models/init.py:1-14
章节来源
- backend/alembic/env.py:1-89
- backend/app/config.py:1-17
- backend/app/database.py:1-29
- backend/app/models/init.py:1-14
性能考虑
- 索引设计
- 初始迁移已为高频查询字段建立索引,有助于提升查询性能。
- 对于大表,建议在维护窗口内重建索引,避免阻塞。
- 迁移窗口
- 将DDL密集型操作安排在低峰时段,减少对线上服务的影响。
- 幂等性
- 迁移脚本应具备幂等特性,避免重复执行造成资源浪费。
章节来源
故障排查指南
- 常见问题
- 迁移失败:检查DATABASE_URL是否正确,确认数据库可达。
- 模型未识别:确保models/init.py导出了新增模型。
- 在线/离线模式混淆:确认运行环境与配置文件一致。
- 排查步骤
- 查看日志:调整alembic.ini中的日志级别以获取更详细输出。
- 回滚验证:使用downgrade验证回滚路径是否完整。
- 数据核对:迁移完成后执行简单查询,核对关键索引与约束是否生效。
章节来源
- backend/alembic.ini:115-150
- backend/alembic/env.py:33-89
- backend/alembic/versions/488d0bd5ab01_initial_migration.py:114-128
结论
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