Files
meijiaka-zy/python-api/app/crud/avatar.py
T

105 lines
3.1 KiB
Python

"""
Avatar CRUD 操作
================
形象克隆记录的数据访问层。
"""
from datetime import UTC, datetime, timedelta
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.crud.base import CRUDBase
from app.models.avatar import Avatar
from app.schemas.avatar import AvatarCreate, AvatarUpdate
class CRUDAvatar(CRUDBase[Avatar, AvatarCreate, AvatarUpdate]):
"""Avatar 数据访问对象"""
def __init__(self) -> None:
super().__init__(Avatar)
async def get_multi_by_user(
self, db: AsyncSession, *, user_id: str, skip: int = 0, limit: int = 100
) -> list[Avatar]:
"""获取用户的形象列表(排除已软删除)"""
result = await db.execute(
select(Avatar)
.where(Avatar.user_id == user_id)
.where(Avatar.deleted_at.is_(None))
.offset(skip)
.limit(limit)
.order_by(Avatar.created_at.desc())
)
return list(result.scalars().all())
async def soft_delete(self, db: AsyncSession, *, id: str, commit: bool = True) -> Avatar | None:
"""软删除形象记录"""
obj = await self.get(db, id)
if obj:
obj.deleted_at = datetime.now(UTC)
if commit:
await db.commit()
await db.refresh(obj)
else:
await db.flush()
return obj
async def get_stuck_tasks(
self,
db: AsyncSession,
processing_statuses: list[str],
timeout_minutes: int = 30,
limit: int = 100,
) -> list[Avatar]:
"""获取卡住的任务(超过指定时间未更新的处理中任务)
Args:
db: 数据库会话
processing_statuses: 需要检查的处理中状态列表
timeout_minutes: 超时时间(分钟)
limit: 最大返回数量
"""
timeout_threshold = datetime.now(UTC) - timedelta(minutes=timeout_minutes)
result = await db.execute(
select(Avatar)
.where(Avatar.status.in_(processing_statuses))
.where(Avatar.deleted_at.is_(None))
.where(Avatar.updated_at < timeout_threshold)
.limit(limit)
.order_by(Avatar.updated_at.asc())
)
return list(result.scalars().all())
async def get_by_status_in(
self,
db: AsyncSession,
statuses: list[str],
updated_before: datetime | None = None,
limit: int = 100,
) -> list[Avatar]:
"""根据状态列表查询任务
Args:
db: 数据库会话
statuses: 状态列表
updated_before: 更新时间早于该时间的记录
limit: 最大返回数量
"""
query = select(Avatar).where(Avatar.status.in_(statuses)).where(Avatar.deleted_at.is_(None))
if updated_before:
query = query.where(Avatar.updated_at < updated_before)
query = query.limit(limit).order_by(Avatar.updated_at.asc())
result = await db.execute(query)
return list(result.scalars().all())
# 全局单例
avatar = CRUDAvatar()