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

152 lines
5.0 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.
# 数据库迁移工具变更说明
## 版本:Django版本 v2.0 (2026-09-04)
### 概述
基于FastAPI版本的`migrate_db.py`设计思路,实现Django项目的跨数据库迁移工具。
### 核心设计(严格参考FastAPI版本)
**关键设计原则:**
1. **使用ORM模型定义表结构**(方言可移植)
2. **按拓扑序逐表迁移**
3. **显式带id批量插入**
4. **按方言重置自增序列**
### 主要改动
#### 1. 模型加载方式
**FastAPI版本:**
```python
from core.database import Base
from core.app import create_app
create_app() # 加载所有模型填充 Base.metadata
```
**Django版本:**
```python
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. 类型映射
```python
def _get_sa_type(field):
"""将 Django 字段类型转换为 SQLAlchemy 类型"""
# CharField → String(max_length)
# IntegerField → Integer
# DateTimeField → DateTime
# BooleanField → Boolean
# TextField → Text
# ...
```
#### 3. 表结构创建
**FastAPI版本:**
```python
Base.metadata.create_all(dst_engine) # 使用ORM模型的metadata
```
**Django版本:**
```python
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类型
### 使用方式
```bash
# 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. 优化大表迁移性能(分页+并行)