d3069d423b
- CRUD 新增 get_by_names_and_level() 批量查分类 - CRUD 新增 get_active_by_categories() 批量查素材 - CRUD 新增 increment_usage_count_batch() 批量更新 usage_count - 重写 batch_match:从 N 次 DB 往返降到 3 次(查分类 + 查素材 + UPDATE) - Redis 改用 pipeline 批量 sadd + expire - 解决并发/连接池不足导致的间歇性 500 错误
81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
"""
|
|
素材 CRUD
|
|
=========
|
|
"""
|
|
|
|
from sqlalchemy import select, update
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.crud.base import CRUDBase
|
|
from app.models.broll_material import BrollMaterial
|
|
|
|
|
|
class BrollMaterialCRUD(CRUDBase[BrollMaterial]):
|
|
"""素材数据访问"""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__(BrollMaterial)
|
|
|
|
async def get_active_by_category_and_duration(
|
|
self,
|
|
db: AsyncSession,
|
|
*,
|
|
category_id: int,
|
|
min_duration: float,
|
|
) -> list[BrollMaterial]:
|
|
"""
|
|
获取指定分类下、时长大于等于要求、状态为 active 的素材列表
|
|
"""
|
|
result = await db.execute(
|
|
select(BrollMaterial).where(
|
|
BrollMaterial.category_id == category_id,
|
|
BrollMaterial.duration >= min_duration,
|
|
BrollMaterial.status == "active",
|
|
)
|
|
)
|
|
return list(result.scalars().all())
|
|
|
|
async def get_active_by_categories(
|
|
self, db: AsyncSession, *, category_ids: list[int]
|
|
) -> list[BrollMaterial]:
|
|
"""批量获取指定分类下状态为 active 的素材列表(不过滤时长)"""
|
|
if not category_ids:
|
|
return []
|
|
result = await db.execute(
|
|
select(BrollMaterial).where(
|
|
BrollMaterial.category_id.in_(category_ids),
|
|
BrollMaterial.status == "active",
|
|
)
|
|
)
|
|
return list(result.scalars().all())
|
|
|
|
async def increment_usage_count(
|
|
self, db: AsyncSession, *, material_id: int
|
|
) -> None:
|
|
"""
|
|
原子递增素材使用次数
|
|
|
|
使用 UPDATE ... SET usage_count = usage_count + 1 避免读-改-写竞态。
|
|
"""
|
|
await db.execute(
|
|
update(BrollMaterial)
|
|
.where(BrollMaterial.id == material_id)
|
|
.values(usage_count=BrollMaterial.usage_count + 1)
|
|
)
|
|
|
|
async def increment_usage_count_batch(
|
|
self, db: AsyncSession, *, material_ids: list[int]
|
|
) -> None:
|
|
"""批量原子递增素材使用次数"""
|
|
if not material_ids:
|
|
return
|
|
await db.execute(
|
|
update(BrollMaterial)
|
|
.where(BrollMaterial.id.in_(material_ids))
|
|
.values(usage_count=BrollMaterial.usage_count + 1)
|
|
)
|
|
|
|
|
|
# 导出实例
|
|
broll_material = BrollMaterialCRUD()
|