From 17748d356b0d1c7864e0c2a0bfef47d406bb4df5 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Sun, 30 Aug 2026 17:37:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(tts):=20AI=20Review=20=E9=98=BB=E5=A1=9E?= =?UTF-8?q?=E9=A1=B9=E2=80=94=E2=80=94=E5=8E=BB=E9=99=A4=E7=AB=9E=E6=80=81?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=B8=AD=E5=AF=B9=20repository=20=E5=86=85?= =?UTF-8?q?=E9=83=A8=20session=20=E7=9A=84=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IntegrityError 后不再手动 getattr(repo, 'session').rollback(): SQLAlchemy commit 失败时 session 已自动回滚,直接重查已存在的库即可, 避免依赖 repository 内部实现(scoped_session/async session 下可能失效)。 同时 mypy:_find_or_create_voice_library 的 asset_library_repository 参数 改 Any 类型(port Protocol 声明 async、SQLAlchemy 实现为同步,与 upload/asset_libraries 路由既有惯例一致)。 --- apps/api/app/api/routes/tts.py | 15 ++++++--------- tests/unit/test_tts_save_to_library_assets.py | 1 - 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/api/app/api/routes/tts.py b/apps/api/app/api/routes/tts.py index bfebc6ce3..78b8f8988 100755 --- a/apps/api/app/api/routes/tts.py +++ b/apps/api/app/api/routes/tts.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging -from typing import Optional +from typing import Any, Optional from app.auth import AuthenticatedUser, get_current_user from app.core.celery_app import celery_app @@ -309,7 +309,7 @@ def _find_or_create_voice_library( *, user_id: str, project_repository: ProjectRepository, - asset_library_repository: AssetLibraryRepository, + asset_library_repository: Any, # port Protocol 声明为 async,SQLAlchemy 实现为同步,与 upload/asset_libraries 路由惯例一致用 Any ) -> AssetLibrary: """在用户可访问的项目中找到(或自动创建)voice 素材库。 @@ -341,12 +341,9 @@ def _find_or_create_voice_library( ) try: return asset_library_repository.create(library) - except Exception as e: - if not isinstance(e, IntegrityError): - raise - session = getattr(asset_library_repository, "session", None) - if session is not None: - session.rollback() + except IntegrityError: + # 并发下另一个请求已抢先创建:SQLAlchemy commit 失败后 session 会自动回滚, + # 直接重查返回已存在的库即可(不依赖 repository 的内部 session 实现)。 for lib in asset_library_repository.find_by_project(project.id): kind = lib.kind.value if hasattr(lib.kind, "value") else lib.kind if kind == AssetLibraryKind.VOICE.value: @@ -354,7 +351,7 @@ def _find_or_create_voice_library( raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="配音素材库创建失败,请重试", - ) from e + ) @router.post( diff --git a/tests/unit/test_tts_save_to_library_assets.py b/tests/unit/test_tts_save_to_library_assets.py index f2dd51b69..453a14d98 100644 --- a/tests/unit/test_tts_save_to_library_assets.py +++ b/tests/unit/test_tts_save_to_library_assets.py @@ -88,7 +88,6 @@ class FakeAssetLibraryRepo: def __init__(self, libs=None, fail_integrity=False): self._libs = list(libs or []) self.fail_integrity = fail_integrity - self.session = MagicMock() def find_by_project(self, project_id): return [lib for lib in self._libs if lib.project_id == project_id]