fix: 代码审查问题修复

- unit_of_work.py: 简化为纯 session 上下文管理器,消除 double-close 风险
- validation.py: 移除未使用的 import,简化 _score_to_1x2 逻辑
- repositories.py: 将 func 导入移到模块顶层
- 更新所有 get_uow() 调用点使用新接口(yield session 而非 uow 对象)
This commit is contained in:
shangfangjian
2026-09-15 01:18:35 +08:00
parent 74586aa5b7
commit 53e602b4f6
8 changed files with 40 additions and 86 deletions
+1 -3
View File
@@ -5,7 +5,7 @@ Repository 只负责查询,不负责事务提交。
"""
from __future__ import annotations
from sqlalchemy import select
from sqlalchemy import func, select
from sqlalchemy.orm import selectinload
from sqlalchemy.ext.asyncio import AsyncSession
@@ -38,8 +38,6 @@ class MatchRepository:
self, league_id: int, home_team_id: int, away_team_id: int, date
) -> Match | None:
"""按联赛+主队+客队+日期查找比赛(天级匹配)。"""
from sqlalchemy import func
if hasattr(date, "date"):
date = date.date()
+15 -45
View File
@@ -1,63 +1,33 @@
"""工作单元(Unit of Work):统一事务边界。
使用方式:
async with UnitOfWork(db) as uow:
await uow.matches.get_by_id(1)
await uow.matches.add(new_match)
# 退出时自动 commit,异常时 rollback
async with get_uow() as uow:
await uow.session.get(Match, 1)
await uow.commit()
"""
from __future__ import annotations
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from typing import AsyncGenerator
from sqlalchemy.ext.asyncio import AsyncSession
from src.db.base import AsyncSessionLocal
class UnitOfWork:
"""工作单元:封装事务边界。"""
def __init__(self, session: AsyncSession) -> None:
self._session = session
self.committed = False
@property
def session(self) -> AsyncSession:
return self._session
async def commit(self) -> None:
await self._session.commit()
self.committed = True
async def rollback(self) -> None:
await self._session.rollback()
async def close(self) -> None:
await self._session.close()
async def __aenter__(self) -> "UnitOfWork":
return self
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
if exc_type is not None:
await self.rollback()
await self.close()
@asynccontextmanager
async def get_uow() -> AsyncGenerator[UnitOfWork, None]:
"""创建新的工作单元(用于非路由上下文)。"""
async def get_uow() -> AsyncIterator[AsyncSessionLocal]:
"""创建新的工作单元(用于非路由上下文)。
用法:
async with get_uow() as session:
await session.get(...)
# 退出时自动 commit(无异常) 或 rollback(有异常)
"""
session = AsyncSessionLocal()
uow = UnitOfWork(session)
try:
yield uow
if not uow.committed:
await uow.commit()
yield session
await session.commit()
except Exception:
await uow.rollback()
await session.rollback()
raise
finally:
await uow.close()
await session.close()