# 数据库迁移 **本文引用的文件** - [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) ## 目录 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
脚本位置、日志、URL等"] B["env.py
在线/离线迁移入口"] C["script.py.mako
迁移模板"] end subgraph "模型定义" D["models/__init__.py
导出所有模型"] 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 表
建立索引"] CreateQueries --> CreateRecords["创建 citation_records 表
建立索引"] CreateRecords --> CreateTasks["创建 query_tasks 表
建立索引"] 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