Files
2026-09-11 11:39:07 +08:00

5.0 KiB
Raw Permalink Blame History

数据库迁移工具变更说明

版本:Django版本 v2.0 (2026-09-04)

概述

基于FastAPI版本的migrate_db.py设计思路,实现Django项目的跨数据库迁移工具。

核心设计(严格参考FastAPI版本)

关键设计原则:

  1. 使用ORM模型定义表结构(方言可移植)
  2. 按拓扑序逐表迁移
  3. 显式带id批量插入
  4. 按方言重置自增序列

主要改动

1. 模型加载方式

FastAPI版本:

from core.database import Base
from core.app import create_app
create_app()  # 加载所有模型填充 Base.metadata

Django版本:

from sqlalchemy.orm import declarative_base
Base = declarative_base()

def load_django_models(prefix: str):
    """从 Django 模型动态创建 SQLAlchemy ORM 模型"""
    import django
    django.setup()
    from django.apps import apps

    for model in apps.get_models():
        table_name = model._meta.db_table
        if table_name.startswith(prefix):
            # 动态创建 SQLAlchemy 模型类
            columns = []
            for field in model._meta.get_fields():
                if hasattr(field, 'column'):
                    col_type = _get_sa_type(field)
                    columns.append(Column(field.column, col_type, ...))
            type(table_name, (Base,), {'__tablename__': table_name, ...})

2. 类型映射

def _get_sa_type(field):
    """将 Django 字段类型转换为 SQLAlchemy 类型"""
    # CharField → String(max_length)
    # IntegerField → Integer
    # DateTimeField → DateTime
    # BooleanField → Boolean
    # TextField → Text
    # ...

3. 表结构创建

FastAPI版本:

Base.metadata.create_all(dst_engine)  # 使用ORM模型的metadata

Django版本:

Base.metadata.create_all(dst_engine)  # 使用动态创建的ORM模型的metadata

保持不变的部分

  1. CLI参数结构 - 保持与FastAPI版本一致
  2. 迁移流程 - 建库 → 建表 → 迁移数据 → 重置序列 → 校验
  3. 表迁移顺序 - _BASE_TABLES和_DEP_TABLES保持不变
  4. 数据泵逻辑 - pump_table()函数保持不变
  5. 序列重置逻辑 - PG/MSSQL/Oracle的序列重置保持不变
  6. 校验逻辑 - verify_counts()函数保持不变

成功验证

[迁移开始] 源: mysql:djangoadmin.django.elevue → 目标: postgresql:djangoadmin.django.elevue
[迁移开始] 待迁移 35 张表
[✓] [1/5] 建目标库 完成(耗时 62ms)
[✓] [2/5] 建表结构(35 张表 create_all) 完成(耗时 74ms)
[✓] [3/5] 逐表迁移数据 完成(耗时 37.5s),共 784612 行
[✓] [4/5] 重置自增序列 完成(耗时 2.2s)
[✓] [5/5] 逐表行数校验 完成(耗时 605ms),35 张表全部 PASS
[迁移完成] 成功:784612 行 / 35 张表 / 总耗时 40.8s

迁移的35张表包括:

  • Django内置表(11张):auth_permission, auth_group, auth_user, auth_group_permissions, auth_user_groups, auth_user_user_permissions, django_content_type, django_migrations, django_session, django_admin_log, captcha_captchastore
  • 项目业务表(24张):django_dept, django_menu, django_role, django_user, django_city 等

与FastAPI版本的对比

特性 FastAPI版本 Django版本
模型定义 SQLAlchemy ORM Django模型动态转换
模型加载 from core.database import Base load_django_models()
表结构来源 Python代码定义 Python代码定义(动态)
方言可移植 ✅ ✅
类型映射 原生SA类型 Django→SA类型映射

关键改进

  1. 方言可移植:使用SQLAlchemy原生类型(Integer, String, DateTime等),保证在所有数据库方言中都有对应实现
  2. 动态模型创建:从Django模型自动创建SQLAlchemy ORM模型,无需手动定义
  3. 类型自动映射:自动将Django字段类型转换为SQLAlchemy类型

使用方式

# MySQL → PostgreSQL
python scripts/migrate_db.py \
    --src-driver=mysql --src-host=127.0.0.1 --src-port=3306 \
    --src-db=djangoadmin.django.elevue --src-user=root --src-pass=root \
    --dst-driver=postgresql --dst-host=127.0.0.1 --dst-port=5432 \
    --dst-db=djangoadmin.django.elevue --dst-user=postgres --dst-pass=postgres

# 干跑模式
python scripts/migrate_db.py --dry-run \
    --src-driver=mysql --src-host=127.0.0.1 --src-port=3306 \
    --src-db=djangoadmin.django.elevue --src-user=root --src-pass=root \
    --dst-driver=postgresql --dst-db=test \
    --dst-user=postgres --dst-pass=postgres

文件清单

scripts/
├── migrate_db.py          # 主迁移脚本(Django版本)
├── MIGRATE_README.md      # 详细使用说明
└── CHANGELOG_MIGRATE.md   # 本文件

后续优化方向

  1. 支持增量迁移(基于时间戳)
  2. 支持并行迁移(多表同时迁移)
  3. 添加迁移日志文件输出
  4. 支持迁移进度条显示
  5. 优化大表迁移性能(分页+并行)