You've already forked DataMate
fix(annotation): fix use_new_version to support files without annotation
Problem: use_new_version returned 404 annotation not found for files without annotation, preventing users from switching to new versions. Solution: 1. Query latest file by logical_path 2. Update LabelingProjectFile to point to latest version 3. If annotation exists: clear it and update file_id 4. If no annotation: just update project file snapshot 5. Return new file_id in response
This commit is contained in:
@@ -1723,16 +1723,19 @@ class AnnotationEditorService:
|
||||
"""
|
||||
使用文件新版本并清空标注
|
||||
|
||||
如果文件有多个版本(通过 logical_path 关联),将标注切换到最新版本。
|
||||
如果存在标注记录,会清空标注内容。
|
||||
|
||||
Args:
|
||||
project_id: 标注项目ID
|
||||
file_id: 文件ID
|
||||
file_id: 文件ID(当前关联的文件ID)
|
||||
|
||||
Returns:
|
||||
操作结果
|
||||
"""
|
||||
project = await self._get_project_or_404(project_id)
|
||||
|
||||
# 获取文件信息
|
||||
# 获取当前文件信息
|
||||
file_result = await self.db.execute(
|
||||
select(DatasetFiles)
|
||||
.join(LabelingProjectFile, LabelingProjectFile.file_id == DatasetFiles.id)
|
||||
@@ -1748,7 +1751,46 @@ class AnnotationEditorService:
|
||||
status_code=404, detail=f"文件不存在或不属于该项目: {file_id}"
|
||||
)
|
||||
|
||||
# 获取标注信息
|
||||
# 获取同一逻辑路径下的最新版本文件
|
||||
logical_path = file_record.logical_path
|
||||
latest_file_result = await self.db.execute(
|
||||
select(DatasetFiles)
|
||||
.where(
|
||||
DatasetFiles.dataset_id == project.dataset_id,
|
||||
DatasetFiles.logical_path == logical_path,
|
||||
DatasetFiles.status == "ACTIVE",
|
||||
)
|
||||
.order_by(DatasetFiles.version.desc())
|
||||
.limit(1)
|
||||
)
|
||||
latest_file = latest_file_result.scalar_one_or_none()
|
||||
|
||||
if not latest_file:
|
||||
raise HTTPException(
|
||||
status_code=404, detail=f"找不到该文件的最新版本: {logical_path}"
|
||||
)
|
||||
|
||||
# 如果当前文件已经是最新版本,无需更新
|
||||
if latest_file.id == file_id:
|
||||
return {
|
||||
"fileId": file_id,
|
||||
"previousFileVersion": file_record.version,
|
||||
"currentFileVersion": latest_file.version,
|
||||
"message": "当前文件已是最新版本,无需切换",
|
||||
}
|
||||
|
||||
# 更新 LabelingProjectFile 指向最新版本
|
||||
project_file_result = await self.db.execute(
|
||||
select(LabelingProjectFile).where(
|
||||
LabelingProjectFile.project_id == project.id,
|
||||
LabelingProjectFile.file_id == file_id,
|
||||
)
|
||||
)
|
||||
project_file = project_file_result.scalar_one_or_none()
|
||||
if project_file:
|
||||
project_file.file_id = str(latest_file.id)
|
||||
|
||||
# 获取标注信息(基于原 file_id)
|
||||
annotation_result = await self.db.execute(
|
||||
select(AnnotationResult)
|
||||
.where(
|
||||
@@ -1759,64 +1801,66 @@ class AnnotationEditorService:
|
||||
)
|
||||
annotation = annotation_result.scalar_one_or_none()
|
||||
|
||||
current_file_version = file_record.version
|
||||
|
||||
if not annotation:
|
||||
raise HTTPException(status_code=404, detail=f"标注不存在: {file_id}")
|
||||
|
||||
previous_file_version = annotation.file_version
|
||||
|
||||
if annotation.file_version is not None:
|
||||
if current_file_version <= annotation.file_version:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"文件版本({current_file_version})未更新或低于标注版本({annotation.file_version})",
|
||||
)
|
||||
|
||||
# 清空标注并更新版本号
|
||||
now = datetime.utcnow()
|
||||
cleared_payload: Dict[str, Any] = {}
|
||||
if isinstance(annotation.annotation, dict) and self._is_segmented_annotation(
|
||||
annotation.annotation
|
||||
):
|
||||
segments = self._extract_segment_annotations(annotation.annotation)
|
||||
cleared_segments: Dict[str, Dict[str, Any]] = {}
|
||||
for segment_id, segment_data in segments.items():
|
||||
if not isinstance(segment_data, dict):
|
||||
continue
|
||||
normalized = dict(segment_data)
|
||||
normalized[SEGMENT_RESULT_KEY] = []
|
||||
cleared_segments[str(segment_id)] = normalized
|
||||
|
||||
total_segments = self._resolve_segment_total(annotation.annotation)
|
||||
if total_segments is None:
|
||||
total_segments = len(cleared_segments)
|
||||
if annotation:
|
||||
# 存在标注记录:清空标注并更新文件版本
|
||||
previous_file_version = annotation.file_version
|
||||
|
||||
cleared_payload = {
|
||||
SEGMENTED_KEY: True,
|
||||
"version": annotation.annotation.get("version", 1),
|
||||
SEGMENTS_KEY: cleared_segments,
|
||||
SEGMENT_TOTAL_KEY: total_segments,
|
||||
cleared_payload: Dict[str, Any] = {}
|
||||
if isinstance(annotation.annotation, dict) and self._is_segmented_annotation(
|
||||
annotation.annotation
|
||||
):
|
||||
segments = self._extract_segment_annotations(annotation.annotation)
|
||||
cleared_segments: Dict[str, Dict[str, Any]] = {}
|
||||
for segment_id, segment_data in segments.items():
|
||||
if not isinstance(segment_data, dict):
|
||||
continue
|
||||
normalized = dict(segment_data)
|
||||
normalized[SEGMENT_RESULT_KEY] = []
|
||||
cleared_segments[str(segment_id)] = normalized
|
||||
|
||||
total_segments = self._resolve_segment_total(annotation.annotation)
|
||||
if total_segments is None:
|
||||
total_segments = len(cleared_segments)
|
||||
|
||||
cleared_payload = {
|
||||
SEGMENTED_KEY: True,
|
||||
"version": annotation.annotation.get("version", 1),
|
||||
SEGMENTS_KEY: cleared_segments,
|
||||
SEGMENT_TOTAL_KEY: total_segments,
|
||||
}
|
||||
|
||||
# 更新标注记录指向新文件
|
||||
annotation.file_id = str(latest_file.id)
|
||||
annotation.annotation = cleared_payload
|
||||
annotation.annotation_status = ANNOTATION_STATUS_NO_ANNOTATION
|
||||
annotation.file_version = latest_file.version
|
||||
annotation.updated_at = now
|
||||
|
||||
await self.db.commit()
|
||||
await self.db.refresh(annotation)
|
||||
|
||||
await self._sync_annotation_to_knowledge(
|
||||
project,
|
||||
latest_file,
|
||||
cleared_payload,
|
||||
annotation.updated_at or now,
|
||||
)
|
||||
|
||||
return {
|
||||
"fileId": str(latest_file.id),
|
||||
"previousFileVersion": previous_file_version,
|
||||
"currentFileVersion": latest_file.version,
|
||||
"message": "已切换到新版本并清空标注",
|
||||
}
|
||||
else:
|
||||
# 不存在标注记录:只需更新项目文件快照
|
||||
await self.db.commit()
|
||||
|
||||
annotation.annotation = cleared_payload
|
||||
annotation.annotation_status = ANNOTATION_STATUS_NO_ANNOTATION
|
||||
annotation.file_version = current_file_version
|
||||
annotation.updated_at = now
|
||||
|
||||
await self.db.commit()
|
||||
await self.db.refresh(annotation)
|
||||
|
||||
await self._sync_annotation_to_knowledge(
|
||||
project,
|
||||
file_record,
|
||||
cleared_payload,
|
||||
annotation.updated_at or now,
|
||||
)
|
||||
|
||||
return {
|
||||
"fileId": file_id,
|
||||
"previousFileVersion": previous_file_version,
|
||||
"currentFileVersion": current_file_version,
|
||||
"message": "已使用新版本并清空标注",
|
||||
}
|
||||
return {
|
||||
"fileId": str(latest_file.id),
|
||||
"previousFileVersion": file_record.version,
|
||||
"currentFileVersion": latest_file.version,
|
||||
"message": "已切换到新版本",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user