# 数据库迁移 **本文引用的文件** - [backend/alembic/env.py](file://backend/alembic/env.py) - [backend/alembic.ini](file://backend/alembic.ini) - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py) - [backend/app/core/database.py](file://backend/app/core/database.py) - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/init_db.py](file://backend/init_db.py) - [backend/create_menu_tables.py](file://backend/create_menu_tables.py) - [backend/migrate_indicators.py](file://backend/migrate_indicators.py) - [backend/init_indicator_templates.py](file://backend/init_indicator_templates.py) - [backend/app/core/config.py](file://backend/app/core/config.py) - [docs/database.md](file://docs/database.md) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本设计文档围绕基于 Alembic 的数据库迁移框架展开,系统阐述版本化数据库变更管理流程、迁移策略与最佳实践,并结合仓库现有迁移脚本与模型定义,给出迁移脚本编写规范、命名约定、初始结构演进策略、数据保护与回滚机制,以及迁移执行命令与工具使用指南。文档同时提供可视化图示帮助读者快速理解迁移架构与数据流。 ## 项目结构 后端采用 SQLAlchemy 异步 ORM 与 Alembic 进行数据库版本管理,核心目录与文件如下: - Alembic 配置与环境:backend/alembic.ini、backend/alembic/env.py - 迁移版本脚本:backend/alembic/versions/*.py - 模型定义:backend/app/models/models.py - 数据库连接与会话:backend/app/core/database.py - 初始数据库与测试数据:backend/init_db.py - 菜单与计划表创建脚本:backend/create_menu_tables.py、backend/create_plan_tables.py - 指标表扩展脚本:backend/migrate_indicators.py - 指标模板初始化脚本:backend/init_indicator_templates.py - 系统配置:backend/app/core/config.py - 文档说明:docs/database.md ```mermaid graph TB A["Alembic 配置
backend/alembic.ini"] --> B["Alembic 环境
backend/alembic/env.py"] B --> C["迁移版本脚本
backend/alembic/versions/*"] D["模型定义
backend/app/models/models.py"] --> B E["数据库连接
backend/app/core/database.py"] --> B F["初始数据库脚本
backend/init_db.py"] --> E G["菜单表脚本
backend/create_menu_tables.py"] --> E H["指标扩展脚本
backend/migrate_indicators.py"] --> E I["指标模板初始化
backend/init_indicator_templates.py"] --> E J["系统配置
backend/app/core/config.py"] --> E ``` **图表来源** - [backend/alembic.ini](file://backend/alembic.ini#L1-L44) - [backend/alembic/env.py](file://backend/alembic/env.py#L1-L66) - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L1-L183) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L1-L96) - [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438) - [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39) - [backend/init_db.py](file://backend/init_db.py#L1-L83) - [backend/create_menu_tables.py](file://backend/create_menu_tables.py#L1-L27) - [backend/migrate_indicators.py](file://backend/migrate_indicators.py#L1-L46) - [backend/init_indicator_templates.py](file://backend/init_indicator_templates.py#L1-L375) - [backend/app/core/config.py](file://backend/app/core/config.py#L1-L47) **章节来源** - [backend/alembic.ini](file://backend/alembic.ini#L1-L44) - [backend/alembic/env.py](file://backend/alembic/env.py#L1-L66) - [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438) - [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39) ## 核心组件 - Alembic 环境与配置 - env.py:定义离线/在线迁移执行逻辑,绑定目标元数据 Base.metadata,支持异步引擎连接。 - alembic.ini:配置脚本位置、路径分隔符、数据库 URL(默认 SQLite),日志级别等。 - 模型与元数据 - models.py:定义所有数据模型及其枚举、索引与约束;Base 作为 DeclarativeBase 基类,供 Alembic 识别变更。 - database.py:创建异步引擎与会话工厂,提供依赖注入接口。 - 迁移版本脚本 - 001_initial.py:初始版本,创建 departments、staff、indicators、assessments、assessment_details、salary_records、users 等表及索引。 - 002_template.py:新增指标模板与模板指标关联表,并向 indicators 表动态添加字段(兼容性处理)。 - 辅助脚本 - init_db.py:创建所有表并插入测试数据。 - create_menu_tables.py:创建菜单相关表并初始化默认菜单。 - migrate_indicators.py:直接通过 SQL 为 indicators 表添加字段(非 Alembic 方式)。 - init_indicator_templates.py:初始化各类科室的指标模板数据。 - app/core/config.py:提供 DATABASE_URL 等配置,影响 Alembic 连接目标。 **章节来源** - [backend/alembic/env.py](file://backend/alembic/env.py#L1-L66) - [backend/alembic.ini](file://backend/alembic.ini#L1-L44) - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L1-L183) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L1-L96) - [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438) - [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39) - [backend/init_db.py](file://backend/init_db.py#L1-L83) - [backend/create_menu_tables.py](file://backend/create_menu_tables.py#L1-L27) - [backend/migrate_indicators.py](file://backend/migrate_indicators.py#L1-L46) - [backend/init_indicator_templates.py](file://backend/init_indicator_templates.py#L1-L375) - [backend/app/core/config.py](file://backend/app/core/config.py#L1-L47) ## 架构总览 下图展示 Alembic 在本项目中的运行时架构:env.py 读取 alembic.ini 配置,绑定 models.py 中的 Base.metadata,通过异步引擎连接数据库,按版本脚本顺序执行 upgrade/downgrade。 ```mermaid graph TB subgraph "Alembic 运行时" CFG["alembic.ini
配置文件"] --> ENV["env.py
迁移入口"] ENV --> META["models.py: Base.metadata
目标元数据"] ENV --> ENG["database.py: AsyncEngine
异步引擎"] ENV --> V001["versions/001_initial.py
初始迁移"] ENV --> V002["versions/002_template.py
模板迁移"] end ENG --> DB["数据库实例
SQLite 或 PostgreSQL"] META --> DB V001 --> DB V002 --> DB ``` **图表来源** - [backend/alembic.ini](file://backend/alembic.ini#L1-L44) - [backend/alembic/env.py](file://backend/alembic/env.py#L1-L66) - [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438) - [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39) - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L1-L183) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L1-L96) ## 详细组件分析 ### 组件A:Alembic 环境与配置 - 功能职责 - 离线模式:直接从 alembic.ini 读取 sqlalchemy.url,配置上下文并执行迁移。 - 在线模式:通过 async_engine_from_config 创建异步引擎,连接数据库后执行迁移。 - 目标元数据:绑定 models.Base.metadata,确保基于 ORM 模型的自动检测与版本生成。 - 关键点 - 异步迁移:env.py 使用 asyncio 协程驱动异步引擎,避免阻塞。 - 日志配置:alembic.ini 控制日志级别与输出格式,便于调试。 - 命令与工具 - 生成迁移:alembic revision --autogenerate -m "描述" - 执行迁移:alembic upgrade head - 回滚迁移:alembic downgrade -1 ```mermaid sequenceDiagram participant CLI as "命令行" participant Env as "env.py" participant Cfg as "alembic.ini" participant Meta as "models.Base.metadata" participant Eng as "AsyncEngine" participant DB as "数据库" CLI->>Env : 运行迁移命令 Env->>Cfg : 读取配置(sqlalchemy.url) Env->>Meta : 绑定目标元数据 Env->>Eng : 创建异步引擎 Env->>DB : 连接并执行迁移 DB-->>Env : 返回迁移结果 Env-->>CLI : 输出状态 ``` **图表来源** - [backend/alembic/env.py](file://backend/alembic/env.py#L21-L65) - [backend/alembic.ini](file://backend/alembic.ini#L1-L44) - [backend/app/models/models.py](file://backend/app/models/models.py#L23-L25) **章节来源** - [backend/alembic/env.py](file://backend/alembic/env.py#L1-L66) - [backend/alembic.ini](file://backend/alembic.ini#L1-L44) - [docs/database.md](file://docs/database.md#L272-L285) ### 组件B:初始数据库结构与演进 - 初始版本(001_initial) - 创建核心表:departments、staff、indicators、assessments、assessment_details、salary_records、users。 - 定义索引与外键约束,确保查询效率与数据一致性。 - 模板版本(002_template) - 新增指标模板表与模板指标关联表,支持按模板生成指标组合。 - 对 indicators 表进行字段扩展(bs_dimension、target_unit、assessment_method、deduction_standard、data_source、applicable_dept_types、is_veto),并通过列存在性检查避免重复添加。 - 演进策略 - 采用增量迁移:每个版本只做必要变更,保持幂等与可回滚。 - 兼容性处理:在字段添加前检查是否存在,避免生产环境报错。 ```mermaid flowchart TD Start(["开始"]) --> CheckCols["检查指标表字段是否存在"] CheckCols --> AddBs["添加 bs_dimension 字段"] CheckCols --> AddUnit["添加 target_unit 字段"] CheckCols --> AddMethod["添加 assessment_method 字段"] CheckCols --> AddDed["添加 deduction_standard 字段"] CheckCols --> AddSource["添加 data_source 字段"] CheckCols --> AddTypes["添加 applicable_dept_types 字段"] CheckCols --> AddVeto["添加 is_veto 字段"] AddBs --> Done(["完成"]) AddUnit --> Done AddMethod --> Done AddDed --> Done AddSource --> Done AddTypes --> Done AddVeto --> Done ``` **图表来源** - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L65-L91) **章节来源** - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L21-L183) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L21-L96) ### 组件C:数据保护与回滚机制 - 回滚策略 - 每个版本脚本均实现 downgrade,按逆序删除表或字段,确保可回滚到上一版本。 - 建议在生产环境执行回滚前备份数据库。 - 数据保护 - 迁移脚本中对字段添加前进行存在性检查,避免重复执行导致失败。 - 使用事务包装迁移操作,失败时回滚,减少不一致风险。 - 备选脚本 - migrate_indicators.py 通过直接 SQL 扩展字段,适用于紧急修复场景,但不建议作为常规迁移手段。 **章节来源** - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L175-L183) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L93-L96) - [backend/migrate_indicators.py](file://backend/migrate_indicators.py#L9-L42) ### 组件D:迁移脚本编写规范与命名约定 - 版本命名 - 使用递增编号(如 001_initial、002_template),确保顺序正确。 - 文件名与 revision ID 保持一致,便于追踪。 - 脚本结构 - 必须包含 upgrade() 与 downgrade() 函数。 - 字段添加需先检查是否存在,避免重复执行。 - 尽量使用 Alembic API(op.*)而非原生 SQL,保证跨数据库兼容性。 - 注释与元信息 - 在文件头部包含消息、修订 ID、修订者、创建日期等信息,提升可维护性。 **章节来源** - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L1-L20) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L1-L20) ### 组件E:迁移执行命令与工具使用 - 常用命令 - 生成迁移:alembic revision --autogenerate -m "描述" - 执行迁移:alembic upgrade head - 回滚迁移:alembic downgrade -1 - 环境变量与配置 - DATABASE_URL 来自 app/core/config.py,影响 Alembic 连接目标(默认 SQLite,开发环境可切换 PostgreSQL)。 - alembic.ini 中的 sqlalchemy.url 也可直接指定数据库连接字符串。 **章节来源** - [docs/database.md](file://docs/database.md#L272-L285) - [backend/app/core/config.py](file://backend/app/core/config.py#L18-L22) - [backend/alembic.ini](file://backend/alembic.ini#L7-L7) ## 依赖关系分析 - 模块耦合 - env.py 依赖 models.Base.metadata 与 app.core.config.settings,确保迁移目标与数据库连接一致。 - database.py 提供 AsyncEngine 与 AsyncSession,被 env.py 用于异步迁移。 - 外部依赖 - Alembic:提供迁移生成、执行与回滚能力。 - SQLAlchemy:ORM 模型与异步引擎,驱动迁移元数据与连接。 - 潜在风险 - 直接 SQL 扩展(如 migrate_indicators.py)与 Alembic 管理的迁移并存,可能造成版本不一致,建议统一迁移到 Alembic。 ```mermaid graph LR ENV["env.py"] --> META["models.Base.metadata"] ENV --> CFG["app/core/config.py"] ENV --> ENG["app/core/database.py"] ENG --> DB["数据库"] V1["001_initial.py"] --> DB V2["002_template.py"] --> DB ``` **图表来源** - [backend/alembic/env.py](file://backend/alembic/env.py#L10-L18) - [backend/app/models/models.py](file://backend/app/models/models.py#L23-L25) - [backend/app/core/config.py](file://backend/app/core/config.py#L18-L22) - [backend/app/core/database.py](file://backend/app/core/database.py#L9-L20) - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L1-L183) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L1-L96) **章节来源** - [backend/alembic/env.py](file://backend/alembic/env.py#L1-L66) - [backend/app/core/database.py](file://backend/app/core/database.py#L1-L39) - [backend/app/models/models.py](file://backend/app/models/models.py#L1-L438) ## 性能考量 - 索引设计 - 初始版本为高频查询字段建立索引(如 departments.dept_type、staff.department_id 等),提升查询性能。 - 迁移执行 - 使用异步引擎减少阻塞;批量 DDL 操作建议合并,避免频繁连接。 - 数据量增长 - 随着 assessments、assessment_details 等表数据增长,需定期评估索引有效性与查询计划。 [本节为通用指导,无需特定文件引用] ## 故障排查指南 - 常见问题 - 迁移失败:检查 downgrade 实现是否完整;确认字段存在性检查逻辑;查看 Alembic 日志级别。 - 连接错误:核对 alembic.ini 与 app/core/config.py 中的 DATABASE_URL;确认数据库服务可用。 - 字段重复添加:确保字段存在性检查逻辑生效;避免 Alembic 与直接 SQL 并行修改同一表。 - 排查步骤 - 查看 Alembic 输出日志,定位失败节点。 - 手动执行 downgrade 指定版本,清理异常状态后再重试。 - 备份数据库后进行回滚与重试。 **章节来源** - [backend/alembic/env.py](file://backend/alembic/env.py#L21-L65) - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L175-L183) - [backend/alembic/versions/002_template.py](file://backend/alembic/versions/002_template.py#L93-L96) - [backend/alembic.ini](file://backend/alembic.ini#L20-L43) ## 结论 本项目采用 Alembic 管理数据库版本,结合 SQLAlchemy 异步 ORM 与明确的迁移脚本规范,实现了从初始结构到模板化的演进。通过字段存在性检查、完善的 downgrade 与日志配置,提升了迁移的安全性与可维护性。建议未来逐步将直接 SQL 扩展迁移纳入 Alembic 管理,统一迁移策略,确保版本一致性与可追溯性。 [本节为总结性内容,无需特定文件引用] ## 附录 ### A. 迁移命令速查 - 生成迁移:alembic revision --autogenerate -m "描述" - 执行迁移:alembic upgrade head - 回滚迁移:alembic downgrade -1 **章节来源** - [docs/database.md](file://docs/database.md#L272-L285) ### B. 初始数据库结构概览 - 核心表 - departments、staff、indicators、assessments、assessment_details、salary_records、users - 关键索引 - 高频过滤字段建立索引,如 dept_type、parent_id、department_id、status 等 - 约束与枚举 - 外键约束、唯一约束、Check 约束与枚举类型(如 DeptType、IndicatorType 等) **章节来源** - [backend/alembic/versions/001_initial.py](file://backend/alembic/versions/001_initial.py#L22-L182) - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L438)