105 lines
3.1 KiB
Python
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()
|