Files
djangoadmin-wiki/DjangoAdmin_FastAPI_NaiveVue/zh/volume1/database.md
T
2026-09-12 23:12:15 +08:00

460 lines
17 KiB
Markdown
Raw 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.
# 数据库初始化
本章节介绍如何初始化项目数据库,包括建库、建表、导入种子数据以及后续的数据库迁移管理。
项目支持多种数据库,数据库脚本按类型存放在 `document/` 目录下:
```
document/
├── mysql/ # MySQL 脚本
│ └── djangoadmin.fastapi.elevue.sql
├── postgresql/ # PostgreSQL 脚本
│ └── djangoadmin.fastapi.elevue.sql
├── sqlserver/ # SQL Server 脚本
│ └── djangoadmin.fastapi.elevue.sql
├── sqlite/ # SQLite 脚本
│ └── djangoadmin.fastapi.elevue.sql
└── oracle/ # Oracle 脚本
└── djangoadmin.fastapi.elevue.sql
```
:::tip 温馨提示
数据库初始化前,请确保已完成以下准备工作:
1. 目标数据库服务已启动(如 MySQL 8.0+)
2. `.env` 文件中的 `DB_DRIVER` 和数据库连接信息已正确配置
3. Python 依赖已安装(`pip install -r requirements.txt`)
:::
## 方式一:手动初始化(推荐)
手动初始化是最直接、最可控的方式,适合开发环境和生产环境。
### 第一步:创建数据库
根据你使用的数据库类型,手动创建数据库。
**MySQL**:
```sql
CREATE DATABASE `djangoadmin.fastapi.elevue`
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
```
**PostgreSQL**:
```sql
CREATE DATABASE "djangoadmin.fastapi.elevue"
WITH ENCODING 'UTF8'
LC_COLLATE = 'zh_CN.UTF-8'
LC_CTYPE = 'zh_CN.UTF-8'
TEMPLATE = template0;
```
**SQL Server**:
```sql
CREATE DATABASE [djangoadmin.fastapi.elevue]
COLLATE Chinese_PRC_CI_AS;
```
**SQLite**:
无需手动创建,指定文件路径即可(如 `DB_DATABASE=./data/app.db`),首次启动时自动创建文件。
**Oracle**:
Oracle 没有"建库"概念,schema 即连接用户。需由 DBA 预先创建表空间和用户:
```sql
-- 创建表空间
CREATE TABLESPACE djangoadmin
DATAFILE 'djangoadmin.dbf' SIZE 100M
AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED;
-- 创建用户并授权
CREATE USER djangoadmin IDENTIFIED BY your_password
DEFAULT TABLESPACE djangoadmin
TEMPORARY TABLESPACE temp;
GRANT CONNECT, RESOURCE, CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE TRIGGER TO djangoadmin;
```
### 第二步:导入数据库脚本
进入 `document/` 目录,根据你使用的数据库类型选择对应的脚本文件夹,导入其中的 SQL 文件。
**MySQL**:
```bash
# 使用 mysql 命令行导入
mysql -uroot -p djangoadmin.fastapi.elevue < document/mysql/djangoadmin.fastapi.elevue.sql
# 或使用 Navicat 等工具:右键数据库 → 运行 SQL 文件 → 选择 document/mysql/djangoadmin.fastapi.elevue.sql
```
**PostgreSQL**:
```bash
# 使用 psql 命令行导入
psql -U postgres -d djangoadmin.fastapi.elevue -f document/postgresql/djangoadmin.fastapi.elevue.sql
# 或使用 Navicat 等工具:右键数据库 → 运行 SQL 文件 → 选择 document/postgresql/djangoadmin.fastapi.elevue.sql
```
**SQL Server**:
```bash
# 使用 sqlcmd 命令行导入
sqlcmd -S localhost -U sa -P your_password -d djangoadmin.fastapi.elevue -i document/sqlserver/djangoadmin.fastapi.elevue.sql
# 或使用 Navicat 等工具:右键数据库 → 运行 SQL 文件 → 选择 document/sqlserver/djangoadmin.fastapi.elevue.sql
# 或使用 SSMS(SQL Server Management Studio):打开 SQL 文件 → 执行
```
**SQLite**:
```bash
# 使用 sqlite3 命令行导入
sqlite3 ./data/app.db < document/sqlite/djangoadmin.fastapi.elevue.sql
# 或使用 Navicat 等工具:打开数据库文件 → 运行 SQL 文件 → 选择 document/sqlite/djangoadmin.fastapi.elevue.sql
```
**Oracle**:
```bash
# 使用 sqlplus 命令行导入
sqlplus djangoadmin/your_password@127.0.0.1:1521/XE @document/oracle/djangoadmin.fastapi.elevue.sql
# 或使用 Navicat 等工具:打开连接 → 运行 SQL 文件 → 选择 document/oracle/djangoadmin.fastapi.elevue.sql
```
:::tip 温馨提示
Oracle 用户需要有 CREATE TABLE、CREATE SEQUENCE、CREATE TRIGGER 权限。脚本会自动为 Integer 主键补建 sequence + BEFORE INSERT 触发器实现自增。
:::
### 第三步:配置 .env
确保 `.env` 文件中的数据库驱动和连接信息与你使用的数据库一致:
```bash
# ============================================================
# 数据库驱动配置
# 取消对应数据库的注释即可切换,同一时间仅启用一种数据库
# ============================================================
# ------------------------------------------------------------
# MySQL(默认)
# 说明:开源关系型数据库,适用性广泛,为本项目默认数据库
# ------------------------------------------------------------
DB_DRIVER=mysql # 数据库驱动类型
DB_HOST=127.0.0.1 # 数据库主机地址
DB_PORT=3306 # 数据库端口(MySQL 默认 3306)
DB_DATABASE=djangoadmin.fastapi.elevue # 数据库名称
DB_USERNAME=root # 数据库用户名
DB_PASSWORD=your_password # 数据库密码(请修改为实际密码)
# ------------------------------------------------------------
# PostgreSQL
# 说明:功能强大的开源对象关系型数据库,支持高级特性
# ------------------------------------------------------------
# DB_DRIVER=postgresql # 数据库驱动类型
# DB_HOST=127.0.0.1 # 数据库主机地址
# DB_PORT=5432 # 数据库端口(PostgreSQL 默认 5432)
# DB_DATABASE=djangoadmin.fastapi.elevue # 数据库名称
# DB_USERNAME=postgres # 数据库用户名
# DB_PASSWORD=your_password # 数据库密码(请修改为实际密码)
# ------------------------------------------------------------
# SQL Server
# 说明:微软企业级关系型数据库,适用于 Windows 生态场景
# ------------------------------------------------------------
# DB_DRIVER=mssql # 数据库驱动类型
# DB_HOST=127.0.0.1 # 数据库主机地址
# DB_PORT=1433 # 数据库端口(SQL Server 默认 1433)
# DB_DATABASE=djangoadmin.fastapi.elevue # 数据库名称
# DB_USERNAME=sa # 数据库用户名
# DB_PASSWORD=your_password # 数据库密码(请修改为实际密码)
# ------------------------------------------------------------
# SQLite
# 说明:轻量级嵌入式文件数据库,适用于本地开发与测试
# ------------------------------------------------------------
# DB_DRIVER=sqlite # 数据库驱动类型
# DB_DATABASE=./data/app.db # 数据库文件路径(相对于项目根目录)
# ------------------------------------------------------------
# Oracle
# 说明:企业级关系型数据库,适用于大型企业应用场景
# ------------------------------------------------------------
# DB_DRIVER=oracle # 数据库驱动类型
# DB_HOST=127.0.0.1 # 数据库主机地址
# DB_PORT=1521 # 数据库端口(Oracle 默认 1521)
# DB_DATABASE=XE # 数据库名称(Oracle 实例名,如 XE、ORCL)
# DB_USERNAME=djangoadmin # 数据库用户名
# DB_PASSWORD=your_password # 数据库密码(请修改为实际密码)
```
:::tip 配置说明
1. 默认启用 MySQL,如需切换数据库,请注释掉 MySQL 相关配置,并取消对应数据库配置的注释。
2. 所有密码占位符请替换为实际数据库密码。
3. 仅需配置一种数据库即可,多个数据库配置同时启用会导致连接冲突。
:::
### 第四步:验证
启动后端服务,访问 Swagger 文档验证数据库连接是否正常:
```bash
python src/main.py
```
打开浏览器访问 `http://127.0.0.1:8031/docs`,尝试调用登录接口,如能正常返回则说明数据库初始化成功。
![](/volume1/database/1.png)
![](/volume1/database/2.png)
:::tip 温馨提示
手动初始化的优势:
1. 可以精确控制导入过程,查看每条 SQL 的执行结果。
2. 可以根据需要只导入部分表或数据。
3. 适合生产环境,配合 DBA 的数据库管理流程。
4. 不依赖 Python 环境,纯 SQL 操作。
:::
## 方式二:脚本初始化(备选)
项目提供了 `init_db.py` 脚本,可以自动完成数据库初始化。脚本会根据 `.env` 中的 `DB_DRIVER` 配置,自动选择对应的数据库方言执行初始化。
```bash
# 执行数据库初始化
python scripts/init_db.py
```
:::tip 初始化内容
`scripts/init_db.py` 脚本按 `DB_DRIVER` 分方言执行,自动完成以下操作:
1. **创建数据库**:检测目标数据库是否存在,不存在则自动创建
- MySQL:`CREATE DATABASE ... DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci`
- PostgreSQL:连接 `postgres` 维护库执行 `CREATE DATABASE`
- SQL Server:连接 `master` 库执行 `CREATE DATABASE`
- SQLite:直接创建数据库文件(`DB_DATABASE` 即文件路径)
- Oracle:仅校验连通性(schema 由 DBA 预建)
2. **导入 SQL 种子数据**:根据 `DB_DRIVER` 查找 `document/{driver}/` 目录下的 SQL 脚本并执行
3. **补建缺失表**:通过 `Base.metadata.create_all(engine)` 根据 ORM 模型定义补建所有数据表
4. **Alembic 版本标记**:调用 `alembic stamp head` 将当前数据库状态标记为迁移基线
脚本源码位于 `scripts/init_db.py`,可通过 `--drop-first` 参数先删除已存在库再重建。
:::
+ 初始化输出示例
```
$ python scripts/init_db.py --drop-first
[INFO] ============================================================
[INFO] 数据库初始化开始
[INFO] ============================================================
[INFO] 检测数据库驱动: mysql
[INFO] 连接 MySQL 服务器: 127.0.0.1:3306
[INFO] 数据库配置: root@127.0.0.1:3306/djangoadmin.fastapi.elevue
[INFO] 数据表前缀: fastapi_
[INFO] 删除已有数据库: djangoadmin.fastapi.elevue
[INFO] 创建数据库: djangoadmin.fastapi.elevue
[INFO] 查找数据库脚本: document\mysql\djangoadmin.fastapi.elevue.sql
[INFO] 导入 SQL 脚本...
[INFO] SQL 脚本导入完成: 784510 条语句
[INFO] 创建数据表...
[INFO] 所有数据表均已存在,无需创建
[INFO] 数据表创建完成: 共 25 张表
[INFO] 标记 Alembic 版本...
2026-09-05 18:12:01,479 | INFO | alembic.runtime.plugins | setup plugin alembic.autogenerate.schemas
2026-09-05 18:12:01,479 | INFO | alembic.runtime.plugins | setup plugin alembic.autogenerate.tables
2026-09-05 18:12:01,479 | INFO | alembic.runtime.plugins | setup plugin alembic.autogenerate.types
2026-09-05 18:12:01,479 | INFO | alembic.runtime.plugins | setup plugin alembic.autogenerate.constraints
2026-09-05 18:12:01,479 | INFO | alembic.runtime.plugins | setup plugin alembic.autogenerate.defaults
2026-09-05 18:12:01,479 | INFO | alembic.runtime.plugins | setup plugin alembic.autogenerate.comments
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
[INFO] Alembic 版本标记完成
[INFO] ============================================================
[INFO] 数据库初始化完成!
[INFO] ============================================================
```
:::danger 注意事项
1. **不带 `--drop-first`**(默认):创建新表和插入种子数据,**不会删除已有数据**,重复执行是安全的(幂等操作)。
+2. **带 `--drop-first`**:会**先删除已有数据库再重建**,所有数据将丢失,仅适用于开发环境或全新部署。
3. 请确保 `.env` 中的数据库用户具有 `CREATE DATABASE` 和 `CREATE TABLE` 权限。
4. 脚本初始化会根据 `DB_DRIVER` 自动查找 `document/{driver}/` 目录下的 SQL 脚本。
:::
## 多数据库支持
项目通过 `DB_DRIVER` 环境变量切换数据库驱动,无需修改代码。
| 数据库 | DB_DRIVER 值 | 默认端口 | 依赖包 | 脚本目录 |
|:----|:----|:----|:----|:----|
| MySQL | `mysql` | 3306 | PyMySQL | `document/mysql/` |
| PostgreSQL | `postgresql` | 5432 | psycopg[binary] | `document/postgresql/` |
| SQL Server | `mssql` | 1433 | pymssql | `document/sqlserver/` |
| SQLite | `sqlite` | - | 内置 | `document/sqlite/` |
| Oracle | `oracle` | 1521 | oracledb | `document/oracle/` |
:::tip 温馨提示
切换数据库驱动后,需要安装对应的驱动包(如 `pip install psycopg[binary]`),然后按照上述步骤重新初始化数据库。
:::
## 种子数据
初始化完成后,数据库中包含以下默认数据:
| 数据 | 说明 |
|:----|:----|
| 管理员账号 | `admin` / `123456`(超级管理员,ID=1,跳过权限校验) |
| 默认角色 | 超级管理员角色 |
| 默认菜单 | 系统管理、内容管理、监控管理等菜单及权限节点 |
| 数据字典 | 系统内置字典数据 |
| 系统配置 | 系统默认配置项 |
如需额外导入业务字典数据,可执行:
```bash
# 初始化业务字典数据(幂等,按 code 判重,已存在跳过)
python scripts/seed_dict.py
```
## 数据库迁移
项目使用 `Alembic` 进行数据库版本迁移管理,确保数据库结构与代码模型保持同步。
+ 迁移文件位置
```
migrations/
├── env.py # 迁移环境配置
└── versions/ # 迁移版本文件
└── 0001_baseline.py # 基线版本
```
+ 生成增量迁移
当修改了 ORM 模型(如新增字段、修改表结构)后,需要生成增量迁移文件:
```bash
# 自动生成迁移脚本(Alembic 会对比当前模型与数据库的差异)
alembic revision --autogenerate -m "描述本次变更"
```
+ 执行迁移
```bash
# 应用所有待执行的迁移
alembic upgrade head
```
+ 版本标记
如果数据库已经手动同步到最新结构,可以标记当前版本:
```bash
# 标记当前数据库为最新版本
alembic stamp head
```
:::tip 迁移工作流
典型的数据库迁移工作流如下:
```
1. 修改 ORM 模型(src/modules/**/models.py)
2. 生成迁移脚本:alembic revision --autogenerate -m "描述本次变更"
3. 检查生成的迁移文件(migrations/versions/ 目录)
4. 执行迁移:alembic upgrade head
5. 验证数据库结构变更
```
:::
## Makefile 数据库命令速查
:::tip Windows 用户注意
`make` 命令是 Linux / macOS 系统自带的构建工具,Windows 系统默认不包含。Windows 用户可直接执行"对应命令"列所示的原始命令,如 `python scripts/init_db.py`、`alembic revision --autogenerate` 等。如需使用 `make`,可通过 `scoop install make` 或 `choco install make` 安装。
:::
| 命令 | 对应命令 | 说明 |
|:----|:----|:----|
| `make db-init` | `python scripts/init_db.py` | 初始化数据库(建库 + 建表 + 种子数据 + alembic stamp) |
| `make seed-dict` | `python scripts/seed_dict.py` | 初始化业务字典数据(幂等,按 code 判重) |
| `make migrate-revision` | `alembic revision --autogenerate` | 生成增量迁移脚本 |
| `make migrate-upgrade` | `alembic upgrade head` | 应用所有待执行的迁移 |
| `make migrate-stamp` | `alembic stamp head` | 标记当前数据库为最新版本 |
| `make db-migrate ARGS="..."` | `python scripts/migrate_db.py ...` | 跨库数据迁移 |
| `make db-migrate-dry-run ARGS="..."` | `python scripts/migrate_db.py ... --dry-run` | 跨库迁移干跑(只核对计划,不写入目标库) |
## 数据库备份与恢复
+ MySQL 备份
```bash
# 备份数据库
mysqldump -uroot -p djangoadmin.fastapi.elevue > backup.sql
# 恢复数据库
mysql -uroot -p djangoadmin.fastapi.elevue < backup.sql
```
+ PostgreSQL 备份
```bash
# 备份数据库
pg_dump -U postgres djangoadmin.fastapi.elevue > backup.sql
# 恢复数据库
psql -U postgres djangoadmin.fastapi.elevue < backup.sql
```
+ SQL Server 备份
```bash
# 备份数据库
sqlcmd -S localhost -U sa -P your_password -Q "BACKUP DATABASE [djangoadmin.fastapi.elevue] TO DISK = 'backup.bak'"
# 恢复数据库
sqlcmd -S localhost -U sa -P your_password -Q "RESTORE DATABASE [djangoadmin.fastapi.elevue] FROM DISK = 'backup.bak'"
# 或使用 Navicat 等工具进行备份恢复
# 或使用 SSMS(SQL Server Management Studio):右键数据库 → 任务 → 备份 / 还原
```
+ SQLite 备份
```bash
# 备份数据库(直接复制文件)
cp ./data/app.db ./data/app_backup.db
# 恢复数据库(替换文件)
cp ./data/app_backup.db ./data/app.db
```
+ Oracle 备份
```bash
# 备份数据库(使用 expdp 数据泵)
expdp djangoadmin/your_password@127.0.0.1:1521/XE directory=DATA_PUMP_DIR dumpfile=backup.dmp full=y
# 恢复数据库(使用 impdp 数据泵)
impdp djangoadmin/your_password@127.0.0.1:1521/XE directory=DATA_PUMP_DIR dumpfile=backup.dmp full=y
# 或使用 Navicat 等工具进行备份恢复
```
## 总结
数据库初始化有两种方式:
```
推荐方式:手动创建数据库 → 导入 document/{driver}/ 目录下的 SQL 脚本 → 配置 .env → 启动验证
备选方式:python scripts/init_db.py(自动完成建库、建表、导入种子数据、Alembic 标记)
```
SQL 脚本按数据库类型分目录存放在 `document/` 下,`init_db.py` 脚本会根据 `.env` 中的 `DB_DRIVER` 自动查找对应目录的脚本文件。后续的模型变更通过 `Alembic` 迁移工具管理,确保数据库结构与代码保持同步。