You've already forked DataMate
feat(annotation): 添加标注项目信息更新功能
- 引入 DatasetMappingUpdateRequest 请求模型支持 name、description、template_id 和 label_config 字段更新
- 在项目接口中添加 PUT /{project_id} 端点用于更新标注项目信息
- 实现更新逻辑包括映射记录查询、配置信息处理和数据库更新操作
- 集成标准响应格式返回更新结果
- 添加异常处理和日志记录确保操作可追溯性
This commit is contained in:
@@ -3,7 +3,7 @@ import math
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Query, Path
|
from fastapi import APIRouter, Depends, HTTPException, Query, Path
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select, update
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from app.db.session import get_db
|
from app.db.session import get_db
|
||||||
@@ -17,6 +17,7 @@ from ..service.template import AnnotationTemplateService
|
|||||||
from ..schema import (
|
from ..schema import (
|
||||||
DatasetMappingCreateRequest,
|
DatasetMappingCreateRequest,
|
||||||
DatasetMappingCreateResponse,
|
DatasetMappingCreateResponse,
|
||||||
|
DatasetMappingUpdateRequest,
|
||||||
DeleteDatasetResponse,
|
DeleteDatasetResponse,
|
||||||
DatasetMappingResponse,
|
DatasetMappingResponse,
|
||||||
)
|
)
|
||||||
@@ -382,3 +383,97 @@ async def delete_mapping(
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error deleting mapping: {e}")
|
logger.error(f"Error deleting mapping: {e}")
|
||||||
raise HTTPException(status_code=500, detail="Internal server error")
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/{project_id}", response_model=StandardResponse[DatasetMappingResponse])
|
||||||
|
async def update_mapping(
|
||||||
|
project_id: str = Path(..., description="映射UUID(path param)"),
|
||||||
|
request: DatasetMappingUpdateRequest = None,
|
||||||
|
db: AsyncSession = Depends(get_db)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
更新标注项目信息
|
||||||
|
|
||||||
|
通过 path 参数 `project_id` 指定要更新的映射(映射的 UUID)。
|
||||||
|
支持更新的字段:
|
||||||
|
- name: 标注项目名称
|
||||||
|
- description: 标注项目描述
|
||||||
|
- template_id: 标注模板ID
|
||||||
|
- label_config: Label Studio XML配置
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
logger.info(f"Update mapping request received: project_id={project_id!r}")
|
||||||
|
|
||||||
|
service = DatasetMappingService(db)
|
||||||
|
|
||||||
|
# 使用 mapping UUID 查询映射记录
|
||||||
|
mapping = await service.get_mapping_by_uuid(project_id)
|
||||||
|
|
||||||
|
if not mapping:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail=f"Mapping not found: {project_id}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 构建更新数据
|
||||||
|
update_values = {}
|
||||||
|
if request.name is not None:
|
||||||
|
update_values["name"] = request.name
|
||||||
|
|
||||||
|
# 从 configuration 字段中读取和更新 description 和 label_config
|
||||||
|
configuration = {}
|
||||||
|
if mapping.configuration:
|
||||||
|
configuration = mapping.configuration.copy() if isinstance(mapping.configuration, dict) else {}
|
||||||
|
|
||||||
|
if request.description is not None:
|
||||||
|
configuration["description"] = request.description
|
||||||
|
if request.label_config is not None:
|
||||||
|
configuration["label_config"] = request.label_config
|
||||||
|
|
||||||
|
if configuration:
|
||||||
|
update_values["configuration"] = configuration
|
||||||
|
|
||||||
|
if request.template_id is not None:
|
||||||
|
update_values["template_id"] = request.template_id
|
||||||
|
|
||||||
|
if not update_values:
|
||||||
|
# 没有要更新的字段,直接返回当前数据
|
||||||
|
return StandardResponse(
|
||||||
|
code=200,
|
||||||
|
message="success",
|
||||||
|
data=mapping
|
||||||
|
)
|
||||||
|
|
||||||
|
# 执行更新
|
||||||
|
from datetime import datetime
|
||||||
|
update_values["updated_at"] = datetime.now()
|
||||||
|
|
||||||
|
result = await db.execute(
|
||||||
|
update(LabelingProject)
|
||||||
|
.where(LabelingProject.id == project_id)
|
||||||
|
.values(**update_values)
|
||||||
|
)
|
||||||
|
await db.commit()
|
||||||
|
|
||||||
|
if result.rowcount == 0:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=500,
|
||||||
|
detail="Failed to update mapping"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 重新获取更新后的数据
|
||||||
|
updated_mapping = await service.get_mapping_by_uuid(project_id)
|
||||||
|
|
||||||
|
logger.info(f"Successfully updated mapping: {project_id}")
|
||||||
|
|
||||||
|
return StandardResponse(
|
||||||
|
code=200,
|
||||||
|
message="success",
|
||||||
|
data=updated_mapping
|
||||||
|
)
|
||||||
|
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error updating mapping: {e}")
|
||||||
|
raise HTTPException(status_code=500, detail="Internal server error")
|
||||||
|
|||||||
@@ -39,9 +39,22 @@ class DatasetMappingCreateResponse(BaseResponseModel):
|
|||||||
labeling_project_id: str = Field(..., description="Label Studio项目ID")
|
labeling_project_id: str = Field(..., description="Label Studio项目ID")
|
||||||
labeling_project_name: str = Field(..., description="Label Studio项目名称")
|
labeling_project_name: str = Field(..., description="Label Studio项目名称")
|
||||||
|
|
||||||
class DatasetMappingUpdateRequest(BaseResponseModel):
|
class DatasetMappingUpdateRequest(BaseModel):
|
||||||
"""数据集映射 更新 请求模型"""
|
"""数据集映射 更新 请求模型
|
||||||
dataset_id: Optional[str] = Field(None, description="源数据集ID")
|
|
||||||
|
支持更新的字段:
|
||||||
|
- name: 标注项目名称
|
||||||
|
- description: 标注项目描述
|
||||||
|
- template_id: 标注模板ID
|
||||||
|
- label_config: Label Studio XML配置
|
||||||
|
"""
|
||||||
|
name: Optional[str] = Field(None, alias="name", description="标注项目名称")
|
||||||
|
description: Optional[str] = Field(None, alias="description", description="标注项目描述")
|
||||||
|
template_id: Optional[str] = Field(None, alias="templateId", description="标注模板ID")
|
||||||
|
label_config: Optional[str] = Field(None, alias="labelConfig", description="Label Studio XML配置")
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
validate_by_name = True
|
||||||
|
|
||||||
class DatasetMappingResponse(BaseModel):
|
class DatasetMappingResponse(BaseModel):
|
||||||
"""数据集映射 查询 响应模型"""
|
"""数据集映射 查询 响应模型"""
|
||||||
|
|||||||
Reference in New Issue
Block a user