diff --git a/video-gen-api/app/services/private_portrait/asset_service.py b/video-gen-api/app/services/private_portrait/asset_service.py index b89b1615..79cafb3b 100644 --- a/video-gen-api/app/services/private_portrait/asset_service.py +++ b/video-gen-api/app/services/private_portrait/asset_service.py @@ -262,6 +262,8 @@ async def handle_validate_callback(db: AsyncSession, *, session_id: str, query_p except Exception as exc: log_operation_error(domain=DOMAIN, event_type=PrivatePortraitEventType.ASSET_GROUP_UPDATE_REMOTE_FAILED.value, source=PrivatePortraitEventSource.CALLBACK.value, user_id=session.user_id, project_id=session.project_id, session_id=session.id, group_id=group.id, exc=exc) await refresh_project_counters(db, [session.project_id]) + await db.flush() + await db.refresh(session) log_operation_event(domain=DOMAIN, event_type=PrivatePortraitEventType.VALIDATE_GET_RESULT_SUCCESS.value, event_status=PrivatePortraitEventStatus.SUCCESS.value, source=PrivatePortraitEventSource.CALLBACK.value, user_id=session.user_id, project_id=session.project_id, session_id=session.id, group_id=group.id, detail={"remote_group_id": group_id, "remote_project_name": session.remote_project_name}) return session except Exception as exc: @@ -324,6 +326,9 @@ async def create_asset(db: AsyncSession, *, user_id: str, project_id: str, paylo asset.raw_response_json = _json(remote_resp) await refresh_project_counters(db, [project.id]) await db.flush() + # created_at / updated_at 来自数据库默认值或 onupdate,flush 后可能处于 expired 状态。 + # 在 async SQLAlchemy 下,响应转换时同步读取 expired 字段会触发 MissingGreenlet。 + await db.refresh(asset) log_operation_event(domain=DOMAIN, event_type=PrivatePortraitEventType.ASSET_CREATE_SUCCESS.value, event_status=PrivatePortraitEventStatus.SUCCESS.value, source=PrivatePortraitEventSource.API.value, user_id=user_id, project_id=project.id, group_id=group.id, asset_id=asset.id, detail={"remote_asset_id": remote_asset_id, "remote_project_name": project.remote_project_name}) return asset except Exception as exc: @@ -398,6 +403,7 @@ async def sync_asset_status(db: AsyncSession, *, user_id: str | None, asset_id: asset.error_message = remote_resp.get("ErrorMessage") or remote_resp.get("error_message") or "素材入库失败" await refresh_project_counters(db, [asset.project_id]) await db.flush() + await db.refresh(asset) log_operation_event( domain=DOMAIN, event_type=PrivatePortraitEventType.ASSET_SYNC_SUCCESS.value, @@ -452,6 +458,7 @@ async def soft_delete_asset(db: AsyncSession, *, user_id: str, asset_id: str) -> asset.remote_delete_status = PrivatePortraitRemoteDeleteStatus.PENDING.value await refresh_project_counters(db, [asset.project_id]) await db.flush() + await db.refresh(asset) log_operation_event(domain=DOMAIN, event_type=PrivatePortraitEventType.ASSET_DELETE_LOCAL.value, event_status=PrivatePortraitEventStatus.SUCCESS.value, source=PrivatePortraitEventSource.API.value, user_id=user_id, project_id=asset.project_id, asset_id=asset.id, detail={"remote_asset_id": asset.remote_asset_id, "remote_project_name": asset.remote_project_name}) return asset