Files

218 lines
11 KiB
Markdown
Raw Permalink Normal View History

2026-09-21 19:55:51 +08:00
# 数据库模型与建表工具改动说明
本次按照《沃林学生管理系统小组分工说明书 V1》修正模型定义,整理范围为 7 个 Model 文件和 1 个建表脚本。各模块继续使用 `core.database.Base`,保留原有 Python 类名和项目目录。
## 一、改动总览
| 模块 | 负责人 | 修改文件 | 模型类 | 最终表名 |
|---|---|---|---|---|
| 学生管理 | 李玉杰 | `models/student.py` | `Student` | `students` |
| 班级管理 | 婷婷 | `models/class_model.py` | `Classes` | `classes` |
| 老师管理 | 张义 | `models/teacher.py` | `Teacher` | `teachers` |
| 班级老师关系 | 张义 | `models/class_teacher.py` | `ClassTeachers` | `class_teachers` |
| 顾问管理 | 薄鑫 | `models/consultant.py` | `Consultant` | `consultants` |
| 成绩管理 | 曾凯 | `models/score.py` | `Score` | `scores` |
| 就业管理 | 南方宇 | `models/employment.py` | `Employment` | `employments` |
| 公共建库建表工具 | 张昕浩 | `utils/create database.py` | — | 使用上述全部模型 |
### 经确认保留的类型
本次没有将所有主键统一为文档中的 `BIGINT`,成绩精度也按已确认的要求保留。
| 项目 | 当前模型类型 |
|---|---|
| 学生、班级、老师、顾问、成绩表的 `id` | `Integer` |
| 班级老师关系表、就业表的 `id` | `BigInteger` |
| 各表关联其他表的外键字段 | `Integer`,与对应模型的主键一致 |
| 成绩字段 `scores.score` | `DECIMAL(4,1)` |
| 薪资字段 `employments.salary` | `DECIMAL(10,2)` |
其中 `class_teachers.class_id`、`class_teachers.teacher_id`、`employments.student_id` 原为 `BigInteger`,经确认改为 `Integer`,解决 MySQL 要求外键与被引用主键类型一致的问题。
## 二、公共字段调整
以下规则落实在各个 Model 文件中,没有增加公共模型文件或额外继承层。
| 字段 | 最终定义及作用 |
|---|---|
| `created_at` | `DATETIME`、不可为空;保留 ORM 创建时间默认值,增加数据库默认值 `CURRENT_TIMESTAMP` |
| `updated_at` | `DATETIME`、不可为空;使用 `onupdate=datetime.now`,增加数据库默认值及 `ON UPDATE CURRENT_TIMESTAMP` |
| `is_deleted` | MySQL `TINYINT`、不可为空;ORM 默认值和数据库默认值均为 `0` |
原先误用 `sqlalchemy.dialects.mssql.TINYINT` 的老师、班级老师关系模型,改为从 `sqlalchemy.dialects.mysql` 导入。
`is_deleted` 是逻辑删除标志。Model 中声明这个字段不会自动过滤查询;接口查询仍需添加 `is_deleted == 0`,删除业务记录应更新该标志。
## 三、学生管理模块
文件:`models/student.py`;负责人:李玉杰。
| 修改项 | 修改前 | 修改后 |
|---|---|---|
| 表名 | `student_info_detail` | `students` |
| 学生编号 | 唯一,但允许为空 | 唯一且 `nullable=False` |
| 学生姓名 | 允许为空 | `nullable=False` |
| 班级外键 | `foreign_key='class_info_detail.id'`,不是有效外键声明 | `ForeignKey('classes.id')`,并设为非空 |
| 顾问外键 | `foreign_key='consultant_info_detail.id'`,不是有效外键声明 | `ForeignKey('consultants.id')`,继续允许为空 |
| 毕业院校字段 | `graduation_school` | `graduate_school` |
| 创建时间字段 | `create_at` | `created_at` |
| 更新时间字段 | `update_at` | `updated_at` |
| 逻辑删除 | `Integer`,允许为空 | MySQL `TINYINT`、非空、默认 `0` |
时间字段按公共规则补齐数据库默认值及非空约束。学生主键、班级外键和顾问外键均保留 `Integer`。
## 四、班级管理模块
文件:`models/class_model.py`;负责人:婷婷。
| 修改项 | 修改前 | 修改后 |
|---|---|---|
| 开课日期 `start_date` | 允许为空 | `nullable=False`,开课时间必填 |
| 更新时间字段 | `update_at` | `updated_at` |
| 备注长度 | `String(100)` | `String(255)` |
| 逻辑删除 | `INTEGER` | MySQL `TINYINT`,补充数据库默认值 `0` |
时间字段增加数据库默认值和数据库自动更新时间设置。保留表名 `classes`、类名 `Classes`、`Integer` 自增主键,以及班级编号唯一且非空的约束。
## 五、老师管理模块
文件:`models/teacher.py`;负责人:张义。
| 修改项 | 修改前 | 修改后 |
|---|---|---|
| 表名 | `teachers_info_detail` | `teachers` |
| 备注长度 | `VARCHAR(2550)` | `VARCHAR(255)` |
| `TINYINT` 来源 | SQL Server 方言 | MySQL 方言 |
| 更新时间 | 仅设置创建时的默认时间 | 补充 `onupdate=datetime.now` 和数据库自动更新时间 |
创建时间增加数据库默认值,逻辑删除增加数据库默认值 `0`。保留 `Integer` 自增主键和老师编号唯一约束。
## 六、班级老师关系模块
文件:`models/class_teacher.py`;负责人:张义。
| 修改项 | 修改前 | 修改后 |
|---|---|---|
| 表名 | `class_teachers_info_detail` | `class_teachers` |
| 班级外键目标 | `ForeignKey('class_id')` | `ForeignKey('classes.id')` |
| 老师外键目标 | `ForeignKey('teacher_id')` | `ForeignKey('teachers.id')` |
| 两个外键字段类型 | `BigInteger` | `Integer`,与班级、老师模型主键匹配 |
| 联合唯一约束 | 未设置 | `(class_id, teacher_id, role)` 联合唯一 |
| 联合唯一约束名称 | — | `uk_class_teacher_role` |
| 时间默认值 | `datetime.now()`,导入模型时就求值 | `datetime.now`,插入记录时再求值 |
| `TINYINT` 来源 | SQL Server 方言 | MySQL 方言 |
补齐时间及逻辑删除的数据库默认值,并为更新时间增加自动更新设置。关系表自身的 `id` 保留 `BigInteger`,类名保留 `ClassTeachers`。
联合唯一约束防止同一个老师以同一个角色被重复分配到同一个班级。
## 七、顾问管理模块
文件:`models/consultant.py`;负责人:薄鑫。
| 修改项 | 修改前 | 修改后 |
|---|---|---|
| 联系电话长度 | `String(11)` | `String(20)` |
| 逻辑删除类型 | `Integer` | MySQL `TINYINT` |
| 数据库默认值 | 未声明 | 补充创建时间、更新时间和逻辑删除默认值 |
保留表名 `consultants`、`Integer` 自增主键、顾问编号唯一且非空的约束,以及其余业务字段。
## 八、成绩管理模块
文件:`models/score.py`;负责人:曾凯。
| 修改项 | 修改前 | 修改后 |
|---|---|---|
| 表名 | `score_info_detail` | `scores` |
| 学生外键目标 | `ForeignKey('student.id')` | `ForeignKey('students.id')` |
| 成绩是否必填 | 允许为空 | `nullable=False` |
| 联合唯一约束名称 | `uk_student_exam_seq` | `uk_scores_student_exam` |
| 备注长度 | `String(225)` | `String(255)` |
| 逻辑删除 | `Integer`,允许为空 | MySQL `TINYINT`、非空、默认 `0` |
创建时间和更新时间补齐非空约束、数据库默认值及自动更新设置;修正注释,明确联合唯一约束是“学生 ID + 考核序次”。
保留 `Integer` 主键及学生外键,成绩精度保留 `DECIMAL(4,1)`,保留成绩范围 `0~100` 的检查约束。一个学生同一次考核只能有一条成绩。
## 九、就业管理模块
文件:`models/employment.py`;负责人:南方宇。
| 修改项 | 修改前 | 修改后 |
|---|---|---|
| 学生外键类型 | `BigInteger` | `Integer`,与学生模型主键匹配 |
| 学生就业唯一约束 | 未设置 | `student_id` 增加 `unique=True` |
| 就业状态长度 | `String(50)` | `String(30)` |
| 就业状态是否必填 | 允许为空 | `nullable=False` |
| 逻辑删除 | `SmallInteger`,允许为空 | MySQL `TINYINT`、非空、默认 `0` |
创建时间和更新时间补齐非空约束、数据库默认值及自动更新设置。修正薪资字段注释:`DECIMAL` 是定点小数。
保留表名 `employments`、`BigInteger` 自增主键、`ForeignKey('students.id')`,以及薪资精度 `DECIMAL(10,2)`。学生外键唯一约束确保每个学生最多对应一条就业信息。
## 十、公共建库建表工具
文件:`utils/create database.py`;负责人:张昕浩。文件名中包含一个空格。
脚本执行流程:
1. 将项目根目录加入当前进程的导入路径,使直接运行此文件时也能导入 `core` 和 `models`。
2. 导入全部 7 个模型,将模型表注册到公共 `Base.metadata`。
3. 检查整数外键与被引用主键的类型是否一致;不一致时列出具体字段并以失败状态退出。
4. 从现有 `core.database.engine` 读取连接设置,先连接不指定数据库的 MySQL 服务。
5. 创建缺失的数据库,字符集为 `utf8mb4`、排序规则为 `utf8mb4_unicode_ci`;当前配置库名为 `student_manager`。
6. 调用 `Base.metadata.create_all(bind=engine)` 创建缺失的表。
7. 查询实际表名,确认全部模型对应的表均存在。
8. 释放数据库连接池;发生数据库或检查错误时输出原因,并返回非零退出码。
在项目根目录运行:
```powershell
python "utils/create database.py"
```
本机已验证使用的解释器命令:
```powershell
& 'D:\conda\envs\ai0720\python.exe' -B -X utf8 '.\utils\create database.py'
```
脚本只创建缺失的库和表,不清空数据、不删除表,也不自动修改已有表结构。
## 十一、验证结果及范围
完成三处外键类型修正后,脚本退出码为 `0`,输出如下:
```text
数据库已就绪:student_manager
已导入的模型表: classes, teachers, consultants, students, class_teachers, scores, employments
建表检查通过:全部模型对应的表均已存在。
```
已经完成的检查包括:
- 7 个模型可以导入,6 个外键目标均能解析。
- 外键与被引用主键在模型中的类型检查通过。
- 7 张表的 MySQL 建表 SQL 可以编译。
- 字段名、非空设置、字符串长度与本次对照结果一致。
- 班级老师关系、成绩和就业的必要唯一约束已在模型中定义。
- 7 个模型可以读取现有数据库中的对应表。
- 文件差异格式检查通过。
本次执行针对已有的 `student_manager` 数据库。`create_all()` 会跳过已有表,因此此结果不等同于已经在全新空库中完成端到端创建测试,也不表示现有数据库已经迁移成当前模型定义。
现有库中的相关主外键仍为原来的 `BIGINT`,成绩列仍为原来的 `DECIMAL(5,2)`;本次没有执行 `ALTER TABLE`,模型里经确认保留的 `Integer` 和 `DECIMAL(4,1)` 不会自动改变这些实库类型。
## 十二、后续接口联调事项
以下配套代码不在本次修改范围内,需要模块负责人继续核对:
| 位置 | 需要核对的内容 |
|---|---|
| `schemas/class_schema.py` 的 `ClassCreate` | 当前缺少 `start_date`,而模型规定开课日期必填 |
| `schemas/class_schema.py` 的 `ClassUpdate` | 当前仍使用 `update_at`,模型字段已统一为 `updated_at` |
| 学生新增及业务编号生成逻辑 | `student_no` 已设为非空;先以空编号执行 `flush()` 再生成编号会违反非空约束,需要与编号生成方案协调 |
本次验证覆盖模型和建表工具,尚未完成上述业务接口的联调验证。