"""客户评级等级配置数据访问。 本层只 flush 不 commit —— 事务边界由 services 层控制。 """ from sqlalchemy import select from sqlalchemy.orm import Session from app.models import CustomerRatingGrade # ==================== 读取 ==================== def list_all(session: Session, *, for_update: bool = False) -> list[CustomerRatingGrade]: """全量等级,按 sort_order 升序、id 兜底(同序次序稳定)。 不分页:等级映射是判定表,数量个位数,分页无意义。 for_update 供区间重叠判定使用:先查后写在无锁时,两管理员并发提交 重叠区间会互判不重叠而双双入库(区间重叠无唯一键可拦)——锁全表行 串行化并发的重叠判定(先到者提交后,后到者在锁下读到新区间即判重叠)。 只读直出(list_grades)不加锁。 """ stmt = select(CustomerRatingGrade).order_by( CustomerRatingGrade.sort_order, CustomerRatingGrade.id ) if for_update: stmt = stmt.with_for_update() return list(session.execute(stmt).scalars()) def get_by_id(session: Session, grade_id: int) -> CustomerRatingGrade | None: """按主键查询。 等级表无下游引用(评级是纯计算器不落评分记录),无需 ``for_update`` 锁行 —— product_repository 锁行防的是并发引用悬空,此处不存在该风险。 """ return session.get(CustomerRatingGrade, grade_id) def get_by_name(session: Session, grade_name: str) -> CustomerRatingGrade | None: """按等级名称查询。 grade_name 是 uk_customer_rating_grades_grade_name 唯一键的键值,先查 用于给出即时业务提示;并发窗口仍存在,最终由 IntegrityError 兜底 (见 rating_service)。 """ stmt = select(CustomerRatingGrade).where(CustomerRatingGrade.grade_name == grade_name) return session.execute(stmt).scalar_one_or_none() # ==================== 写入 ==================== def create(session: Session, grade: CustomerRatingGrade) -> CustomerRatingGrade: """新增等级。只 flush 以取得自增 id。""" session.add(grade) session.flush() return grade def delete(session: Session, grade: CustomerRatingGrade) -> None: """物理删除等级。等级表无下游引用,调用方无需引用保护校验。""" session.delete(grade) session.flush()