[fix]:[FL-205][模型删除时同步删除存储文件]

- 更新 delete_asset 函数,在删除数据库记录前先删除物理文件
- 遍历模型的所有 release,逐个删除其存储路径下的文件
- 使用 try-except 确保文件删除失败不会阻塞数据库清理
- 新增测试用例 test_delete_asset_removes_storage_files 验证文件删除功能

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
chengkai3
2026-06-28 11:15:06 +08:00
parent a9fabc380d
commit 5f0b4b0256
2 changed files with 59 additions and 0 deletions
+11
View File
@@ -888,6 +888,17 @@ def delete_asset(db: Session, asset_id: str) -> bool:
item = get_asset_by_id(db, asset_id)
if not item:
return False
# Delete physical files for all releases before deleting database records
for release in item.releases:
try:
mount = _resolve_mount(db, release.storage_mount_code)
driver = _build_driver_or_400(mount)
driver.delete_path(release.storage_root_path, is_dir=True, recursive=True)
except Exception:
# Log error but continue deletion - don't let file deletion failure block database cleanup
pass
db.delete(item)
db.commit()
_publish_change("asset.deleted", {"action": "deleted", "asset_id": asset_id})
+48
View File
@@ -330,3 +330,51 @@ def test_run_release_dry_run_materializes_directory(tmp_path, monkeypatch) -> No
assert result.output_manifest_json["file_count"] >= 2
finally:
session.close()
def test_delete_asset_removes_storage_files(tmp_path) -> None:
testing_session = _build_sessionmaker()
session: Session = testing_session()
try:
_seed_vfs_mount(session, root_dir=tmp_path / "vfs")
asset = atp_asset_service.create_asset(
session,
AtpAssetCreateRequest(
code="ATP-ASSET-DELETE-TEST",
name="删除测试模型",
voltage_level="500",
tower_type="danhuita",
scene_type="raoji3",
),
actor_user_id="tester",
)
assert asset is not None
# Create a release with files
release = atp_asset_service.create_release_from_archive(
session,
asset_id=asset.id,
release_tag="v1",
archive_filename="release.zip",
archive_content=_build_zip({
"work.atp": b"ATP INPUT",
"README.txt": b"documentation",
}),
actor_user_id="tester",
)
assert release.storage_root_path == "/atp-library/500/danhuita/r1"
# Verify files exist before deletion
storage_path = tmp_path / "vfs" / "atp-library" / "500" / "danhuita" / "r1"
assert storage_path.exists()
assert (storage_path / "work.atp").exists()
assert (storage_path / "README.txt").exists()
# Delete the asset
deleted = atp_asset_service.delete_asset(session, asset.id)
assert deleted is True
# Verify files are deleted
assert not storage_path.exists()
finally:
session.close()