# 系统功能调整改造说明 ## 1. 背景说明 根据最新数据库设计,以下业务表结构已经调整: - `ai_dataset` - `ai_dataset_sample` - `ai_temp_file` - `ai_annotate_task` - `ai_annotate_task_sample` 其中: - `ai_temp_file` 为新增表 - `ai_dataset`、`ai_annotate_task`、`ai_annotate_task_sample` 发生了表名和字段调整 - `ai_dataset_sample` 发生了字段调整 当前后端代码仍然主要基于旧模型、旧表名和本地文件系统目录进行数据集、样本、标注任务和训练样本处理,尚未与新的 `table.sql` 以及 MinIO 主存储模式完全对齐。因此需要先完成系统功能和代码结构层面的改造设计,再实施模型、接口和业务流程改造。 本说明文档用于梳理: - 新旧表结构差异 - 现有代码现状 - 目标业务逻辑 - 需要调整的模块、接口和流程 - 推荐的实施顺序 --- ## 2. 调整目标 本次改造的核心目标如下: 1. 以 `backend/config/settings/table.sql` 为准,统一后端模型与数据库表结构 2. 引入 `ai_temp_file` 作为临时文件中转表,承接 ZIP、视频、图片、音频等原始文件上传 3. 将上传文件统一存入 MinIO,对象存储成为主文件存储后端 4. `ai_dataset` 只负责数据集主记录管理 5. `ai_dataset_sample` 负责数据集样本记录,支持直接上传和从 `ai_temp_file` 导入 6. 根据数据集类型自动执行 ZIP 解压、视频抽帧等导入规则 7. 保持后续标注、训练准备、模型训练流程可继续使用数据集样本 --- ## 3. 现状分析 ### 3.1 当前数据库模型与 `table.sql` 不一致 当前后端模型定义位于: - `backend/apps/core/models.py` 当前序列化器定义位于: - `backend/apps/common/serializers.py` 当前数据集和样本相关视图位于: - `backend/apps/datasets/views/dataset.py` - `backend/apps/datasets/views/dataset_sample.py` - `backend/apps/datasets/views/annotate_task.py` - `backend/apps/datasets/views/annotate_task_sample.py` 当前 MinIO 通用接口位于: - `backend/apps/common/minio_client.py` - `backend/apps/common/views/minio_storage.py` ### 3.2 当前系统仍以本地文件系统为主 目前数据集主流程依赖本地文件目录 `FILESPACE_ROOT_PATH`: - 创建数据集时创建本地目录 - 上传数据时写入本地目录 - 样本读取时从本地文件读取并转 base64 - 删除样本时直接删除本地文件 - 标注合并时在本地生成 XML/JSON 标注文件 - 训练前样本准备时从本地目录复制样本和标注文件 虽然系统已经集成 MinIO 通用文件接口,但 MinIO 目前仍是旁路能力,尚未成为数据集与训练业务的默认存储主链路。 ### 3.3 当前旧模型与新表结构的主要差异 #### 1. `ai_dataset` `table.sql` 中的目标表为 `ai_dataset`,字段包括: - `id` - `dataset_code` - `dataset_name` - `description` - `dataset_type` - `features` - `original_file_path` - `original_file_name` - `dataset_path` - `dataset_count` - `dataset_labels` - `status` - `creator` - `create_time` - `custom1` - `custom2` - `custom3` 当前代码中实际模型为: - 模型名:`AiDataset` - 表名:`ai_algorithm_dataset` 主要问题: - 表名不一致 - 当前模型多出 `algorithm_id`、`algorithm_name` - 当前业务很多地方基于 `algorithm_id` 生成 `dataset_code` 和目录路径 - 新表 `ai_dataset` 中没有 `algorithm_id` 字段,说明当前“数据集绑定算法”的逻辑需要重新定义 #### 2. `ai_dataset_sample` `table.sql` 中目标表仍为 `ai_dataset_sample`,但字段结构已变化: - `saved_filesize` 长度缩短为 `varchar(10)` - 标注字段拆分为 `rectangle` 与 `polygon` 当前代码中模型仍为: - 模型名:`AiDatasetSample` - 表名:`ai_dataset_sample` 主要问题: - 当前模型使用单一字段 `annotation_content` - 现有标注、审核、合并逻辑均围绕 `annotation_content` 展开 - 新表结构拆成 `rectangle`、`polygon` 后,需要重新设计样本标注存储格式和兼容逻辑 #### 3. `ai_temp_file` `table.sql` 中新增: - 表名:`ai_temp_file` 字段包括: - `id` - `original_path` - `original_name` - `original_type` - `bucket_name` - `object_name` - `object_size` - `content_type` - `status` - `create_time` - `custom1` - `custom2` - `custom3` 当前代码现状: - 无对应 Django 模型 - 无对应序列化器 - 无对应业务接口 - 无与数据集导入流程的集成 也就是说,`ai_temp_file` 目前仅存在于 SQL 设计中,代码层完全缺失。 #### 4. `ai_annotate_task` `table.sql` 中目标表为 `ai_annotate_task`,字段包括: - `id` - `algorithm_id` - `task_name` - `annotate_type` - `description` - `dataset_id` - `task_count` - `task_range` - `task_type` - `region_type` - `labels` - `work_type` - `task_team` - `task_leader` - `status` - `creator` - `create_time` - `custom1` - `custom2` - `custom3` 当前代码中实际模型为: - 模型名:`AiDatasetTask` - 表名:`ai_dataset_task` 主要问题: - 表名不一致 - 当前模型承载的是标注任务业务,语义上与新表一致 - 当前模型仍映射旧表 `ai_dataset_task` - 新表改为 `ai_annotate_task` - `dataset_id` 仍然保留,说明原先“单数据集标注任务”的业务处理逻辑不变 这意味着标注任务主表的核心业务逻辑可以保持不变,主要改造点是表名映射与字段对齐。 - 创建任务时继续保存单一 `dataset_id` - 分配样本时继续按所属数据集筛选样本 - 统计任务样本数时继续按单数据集汇总 #### 5. `ai_annotate_task_sample` `table.sql` 中目标表为 `ai_annotate_task_sample`,字段与当前样本任务表接近,主要变化是表名调整。 当前代码中实际模型为: - 模型名:`AiDatasetTaskSample` - 表名:`ai_dataset_task_sample` 主要问题: - 表名不一致 - 与 `ai_annotate_task` 关联的上游表名也已变化 - 现有接口、序列化器、业务逻辑均使用旧模型名和旧表名 --- ## 4. 新业务逻辑梳理 ### 4.1 `ai_temp_file` 临时文件管理 目标定位: - 作为前端上传 ZIP、视频、图片、音频等原始文件的统一入口 - 所有临时文件先上传到 MinIO 的 `tempfile` 桶 - 上传成功后,在 `ai_temp_file` 表中记录文件元数据 - 数据集导入时,优先从 `ai_temp_file` 选择文件来源 建议的文件类型分类: - `01` 图片 - `02` 视频 - `03` 音频 - `04` ZIP 压缩包 - `05` 文本 - `99` 其他 建议状态值: - `01` 已上传 - `02` 已导入数据集 - `03` 已失效 - `09` 已删除 ### 4.2 `ai_dataset` 数据集主表 目标定位: - 只记录数据集定义信息 - 包括名称、类型、标签、样本数、状态等主数据 - 不直接承担临时文件存储职责 页面能力: - 新增数据集 - 修改数据集 - 删除数据集 - 查询数据集列表 - 查看数据集详情 关键变化: - 当前代码中“创建数据集即创建本地目录”的逻辑需要改造 - 改为 MinIO 主存储,`dataset_path` 适合作为 MinIO 逻辑前缀,而不是本地磁盘目录 ### 4.3 `ai_dataset_sample` 数据集样本表 目标定位: - 记录真正进入数据集的样本文件 - 文件实际存储于 MinIO 的 `dataset` 桶 - 每个样本对应一个 MinIO 对象 样本来源有两类: 1. 页面直接上传图片、视频、音频 2. 从 `ai_temp_file` 中选择文件导入 导入规则: - 如果数据集要求是图片类型,而临时文件是 ZIP,则自动解压 ZIP 中符合类型的文件后逐个导入 - 如果数据集要求是图片类型,而临时文件是视频,则根据抽帧规则提取图片后导入 - 如果数据集要求是视频类型,则视频原文件可以直接进入 `ai_dataset_sample` - 如果数据集要求是音频类型,则只导入音频类文件 ### 4.4 `ai_annotate_task` / `ai_annotate_task_sample` 根据现有代码,当前这两张表实际上承载的是标注任务与标注样本任务。 当前逻辑包括: - 创建标注任务 - 分配样本给执行人 - 自动标注 - 人工标注 - 提交审核 - 审核通过/驳回 - 合并标注结果回主样本表 新的表结构已经明确恢复为原先的标注任务设计,因此任务与数据集的关系保持为单数据集模式: - `ai_annotate_task.dataset_id`:记录本次标注任务所属的数据集 - `ai_annotate_task_sample.sample_id`:记录当前任务样本对应的主样本记录 这样可以继续保持以下业务能力: - 创建任务时按数据集分配样本 - 合并标注结果时定位主数据集样本 - 统计任务所属数据集样本数量 确认采用以下方案调整: 1. `ai_annotate_task.dataset_id` 保存本次标注任务所属数据集 2. `ai_annotate_task_sample.sample_id` 保存当前任务样本对应的主样本 3. 通过 `ai_annotate_task.dataset_id -> ai_dataset.id` 可以明确任务属于哪个数据集 4. 通过 `ai_annotate_task_sample.sample_id -> ai_dataset_sample.id` 可以明确任务样本对应哪条主样本记录 5. 原先“单数据集标注任务”的业务处理逻辑保持不变,主要进行表名和模型映射调整 --- ## 5. 目标功能改造方案 ### 5.1 临时文件模块改造 新增模块名称建议: - 临时文件管理 建议新增模型: - `AiTempFile` 建议新增接口: - 临时文件上传 - 临时文件列表查询 - 临时文件详情读取 - 临时文件修改 - 临时文件删除 - 临时文件下载 - 临时文件预览 建议接口示例: - `POST /server/tempfile/upload/` - `GET /server/tempfile/list/` - `GET /server/tempfile/read/` - `PUT /server/tempfile/update/` - `DELETE /server/tempfile/delete/` - `GET /server/tempfile/download/` - `GET /server/tempfile/preview/` 处理流程建议: 1. 前端上传文件 2. 后端识别文件类型 3. 上传到 MinIO `tempfile` 桶 4. 记录 `ai_temp_file` 5. 返回文件 ID、文件名、桶名、对象名、预览地址 ### 5.2 数据集模块改造 目标接口保留并扩展: - 数据集新增 - 数据集修改 - 数据集删除 - 数据集列表查询 - 数据集详情查询 建议废弃或重构当前接口中的以下逻辑: - 在 `createDataset` 中按算法创建本地目录 - 在 `uploadDatasetFile` 中直接把文件落到本地目录 - 在 `generateDatasetImages` 中依赖本地视频目录做抽帧 建议新增业务接口: - 从临时文件导入到数据集 - 直接上传文件到数据集 建议接口示例: - `POST /server/dataset/importFromTempFile/` - `POST /server/dataset/uploadSamples/` ### 5.3 数据集样本模块改造 建议新增或调整能力: - 样本列表查询 - 样本详情查询 - 样本预览 - 样本删除 - 样本批量导入 - 样本批量抽帧导入 - 样本批量解压导入 #### 样本导入统一规则 建议抽象为统一导入服务: - `TempFileImportService` - `DatasetSampleImportService` 建议流程: 1. 根据 `dataset_id` 读取数据集定义 2. 根据 `temp_file_id` 读取临时文件元数据 3. 按数据集类型与临时文件类型执行对应导入策略 4. 将结果文件上传到 MinIO `dataset` 桶 5. 逐条写入 `ai_dataset_sample` 6. 更新 `ai_dataset.dataset_count` 7. 将 `ai_temp_file.status` 更新为已导入 #### 类型转换规则建议 ##### 规则 A:图片数据集 + ZIP 文件 - 解压 ZIP - 仅提取图片类型文件 - 上传到 `dataset` 桶 - 批量写入 `ai_dataset_sample` ##### 规则 B:图片数据集 + 视频文件 - 根据抽帧规则提取图片 - 上传图片到 `dataset` 桶 - 批量写入 `ai_dataset_sample` ##### 规则 C:视频数据集 + 视频文件 - 视频原文件直接上传到 `dataset` 桶 - 写入 `ai_dataset_sample` ##### 规则 D:音频数据集 + ZIP 文件 - 解压 ZIP - 筛选音频文件 - 上传到 `dataset` 桶 - 批量写入 `ai_dataset_sample` ##### 规则 E:图片数据集 + 直接上传图片 - 文件直接上传到 `dataset` 桶 - 写入 `ai_dataset_sample` ### 5.4 标注任务模块改造 当前标注任务能力本身可以保留,但需进行表结构和字段适配。 建议改造点: - 将 `AiDatasetTask` 调整为映射 `ai_annotate_task` - 将 `AiDatasetTaskSample` 调整为映射 `ai_annotate_task_sample` - 所有任务相关接口、序列化器、统计逻辑同步修改 - 保持当前单 `dataset_id` 的标注任务处理逻辑 - 按新表结构对齐字段顺序和表名,不额外引入新的任务关联复杂度 特别说明: - 创建任务时继续选择单一 `dataset_id` - 分配样本时,继续从该数据集下筛选样本 - 合并标注结果时,继续通过 `sample_id` 回写到主样本 - 任务详情、统计、筛选页面继续按单数据集任务展示 ### 5.5 训练样本准备模块改造 这是本次需求中容易被忽略但必须同步改造的部分。 当前训练准备逻辑默认从本地目录读取图片、标注文件和 mask 文件。如果 `ai_dataset_sample` 的真实文件改存 MinIO,则以下功能都会受到影响: - `prepare_algorithm_train_dataset` - 检测任务生成 YOLO 标签 - 分割任务生成 mask、txt、COCO JSON - 训练前复制样本到 `train/val` 目录 人工核实确认新增一层训练样本读取服务: - 如果样本存本地,则直接读取本地文件 - 如果样本存 MinIO,则先下载到训练工作目录或使用本地缓存目录 建议实现: - `DatasetSampleStorageService` - `TrainingDatasetMaterializeService` --- ## 6. 推荐的数据字段调整建议 ### 6.1 `ai_temp_file.original_type` 建议统一存枚举值,而不是自由文本,便于后续导入规则判断。 ### 6.2 `ai_dataset.dataset_path` 建议定义为 MinIO 逻辑目录前缀,例如: - `datasets/{dataset_id}/` 而不再直接绑定本地绝对目录。 ### 6.3 `ai_dataset_sample.saved_path` 当前字段语义是服务器磁盘路径,改造后建议定义为: - MinIO 对象逻辑前缀 - 或对象完整目录前缀 例如: - `datasets/{dataset_id}/images` ### 6.4 `ai_dataset_sample.saved_filename` 建议保留,作为对象文件名。 ### 6.5 `ai_dataset_sample.rectangle` / `polygon` 由于 `table.sql` 已将标注内容拆分为两个字段,建议后续按标注类型分别存储: - 目标检测标注写入 `rectangle` - 多边形标注写入 `polygon` 如果仍需兼容当前前端和自动标注逻辑,可以在服务层临时做统一转换,避免前端一次性改动过大。 --- ## 7. 受影响模块清单 ### 7.1 数据模型层 需要调整或新增: - `backend/apps/core/models.py` - 新增 `AiTempFile` - 调整 `AiDataset` 映射 - 调整 `AiDatasetSample` 字段 - 调整 `AiDatasetTask` 映射 - 调整 `AiDatasetTaskSample` 映射 - 将 `AiDatasetTask` 的表映射从旧表调整到 `ai_annotate_task` - 将 `AiDatasetTaskSample` 的表映射从旧表调整到 `ai_annotate_task_sample` ### 7.2 序列化器层 需要调整: - `backend/apps/common/serializers.py` 建议不要继续全部使用 `fields = "__all__"`,应增加: - 字段级校验 - 类型校验 - 只读字段控制 - 导入规则参数校验 ### 7.3 视图层 重点受影响文件: - `backend/apps/datasets/views/dataset.py` - `backend/apps/datasets/views/dataset_sample.py` - `backend/apps/datasets/views/annotate_task.py` - `backend/apps/datasets/views/annotate_task_sample.py` - `backend/apps/training/views/algorithm_trainrecords.py` ### 7.4 MinIO 能力层 现有通用能力可复用: - 单文件上传 - 批量上传 - ZIP 解压入库 - 视频抽帧入库 - 下载 - 预览 - 预签名地址 但应注意: - 现有 MinIO 接口是通用文件接口 - 业务层仍需新增“文件上传后写业务表”的封装接口 --- ## 8. 推荐接口改造清单 ### 8.1 临时文件接口 - `POST /server/tempfile/upload/` - `GET /server/tempfile/list/` - `GET /server/tempfile/read/` - `PUT /server/tempfile/update/` - `DELETE /server/tempfile/delete/` - `GET /server/tempfile/download/` - `GET /server/tempfile/preview/` ### 8.2 数据集接口 - `POST /server/dataset/create/` - `PUT /server/dataset/update/` - `DELETE /server/dataset/delete/` - `GET /server/dataset/list/` - `GET /server/dataset/read/` - `POST /server/dataset/uploadSamples/` - `POST /server/dataset/importFromTempFile/` ### 8.3 数据集样本接口 - `GET /server/dataset/sample/list/` - `GET /server/dataset/sample/read/` - `DELETE /server/dataset/sample/delete/` - `GET /server/dataset/sample/preview/` - `GET /server/dataset/sample/download/` ### 8.4 任务接口 - `POST /server/annotateTask/create/` - `GET /server/annotateTask/list/` - `GET /server/annotateTask/read/` - `PUT /server/annotateTask/update/` - `DELETE /server/annotateTask/delete/` - `POST /server/annotateTask/assignSamples/` - `POST /server/annotateTask/autoAnnotate/` - `POST /server/annotateTask/submitAudit/` - `POST /server/annotateTask/audit/` - `POST /server/annotateTask/mergeToDataset/` 任务接口改造时需要特别支持: - 创建任务时提交单一 `dataset_id` - 查询任务详情时返回所属数据集信息 - 任务样本列表继续按任务和样本状态过滤,无需额外支持跨数据集来源拆分 --- ## 9. 推荐实施顺序 ### 第一阶段:表结构对齐 目标: - 按 `table.sql` 调整模型和迁移脚本 - 补齐 `AiTempFile` - 完成序列化器基础适配 ### 第二阶段:临时文件模块落地 目标: - 完成 `ai_temp_file` CRUD、下载、预览 - 文件统一上传到 MinIO `tempfile` 桶 ### 第三阶段:数据集导入流程改造 目标: - 支持直接上传到数据集 - 支持从 `ai_temp_file` 导入到 `ai_dataset_sample` - 支持 ZIP 解压导入 - 支持视频抽帧导入 ### 第四阶段:标注任务适配 目标: - 适配 `ai_annotate_task` / `ai_annotate_task_sample` - 调整样本分配、审核、合并逻辑 - 兼容 `rectangle` / `polygon` ### 第五阶段:训练准备适配 目标: - 训练前样本准备流程改为支持 MinIO 数据源 - 保证现有训练功能不因文件存储切换而失效 --- ## 10. 风险与注意事项 ### 10.1 最大风险:表结构变了,但业务主流程仍基于旧字段 尤其是以下两个点影响最大: - `ai_dataset` 不再包含 `algorithm_id` - 标注任务表从旧表名切换为 `ai_annotate_task` 如果不先明确新的业务关联关系,直接改模型会导致: - 数据集创建逻辑失效 - 标注任务创建与样本分配逻辑失效 - 标注合并逻辑失效 ### 10.2 标注任务表名切换带来的兼容风险 标注任务相关模型、接口和统计逻辑当前都绑定旧表名,切换到新表后需要同步适配: - 创建任务时的数据写入表 - 任务样本分配与读取 - 审核状态统计 - 标注结果合并回主样本 - 前端页面的任务详情与列表查询 ### 10.3 文件存储切换后,训练模块必须同步改造 如果只改上传链路,不改训练样本准备链路,会导致: - 数据集页面可正常上传 - 但训练启动时找不到样本文件 ### 10.4 标注字段拆分后,前端与自动标注逻辑也要同步 当前系统大量逻辑直接读写 `annotation_content`,而新表结构改为: - `rectangle` - `polygon` 需要提前定义兼容策略,避免标注页面与自动标注接口全部失效。 --- ## 11. 最终结论 本次需求不是简单新增几个接口,而是一次涉及以下四个层面的系统级改造: - 数据库表结构重构 - 文件存储模式切换为 MinIO 主存储 - 数据集导入链路重构 - 标注与训练链路适配 - 标注任务表结构与命名对齐 建议按“表结构对齐 -> 临时文件模块 -> 数据集导入 -> 标注任务适配 -> 训练准备适配”的顺序分阶段实施。 本次修正确认后,标注任务链路的关系已经清晰: 1. `ai_annotate_task.dataset_id` 记录本次标注任务所属数据集 2. `ai_annotate_task_sample.sample_id` 记录对应的主样本记录 3. 标注任务仍然按单数据集业务逻辑处理 这样可以保持原先标注任务、样本分配、审核和合并回库逻辑不变。 当前最优先要做的事情有三项: 1. 明确 `ai_dataset` 是否还需要与算法关联 2. 将标注任务模型和接口从旧表映射调整到 `ai_annotate_task` 与 `ai_annotate_task_sample` 3. 将 `ai_temp_file` 模块先落地,作为后续所有导入能力的统一入口 只有在这三个基础点明确后,后续 ZIP 解压导入、视频抽帧导入、样本入库、标注任务、训练任务才能稳定衔接。