Files

95 lines
2.5 KiB
Python
Raw Permalink Normal View History

2026-08-03 15:06:29 +08:00
"""
AI Box Sophon Adapter — 告警记录清理
当告警记录超过配置的 max_records 时,自动清理最早的记录及其关联的视频文件。
"""
import logging
import os
import shutil
from sqlalchemy import select, func, asc
from .models.orm import AlarmRecord
logger = logging.getLogger(__name__)
async def trim_alarm_records(db_session, upload_root: str, max_records: int) -> int:
"""
裁剪告警记录,保留最新的 max_records 条
删除超出限制的最早记录,同时清理关联的视频文件目录。
Args:
db_session: SQLAlchemy 异步 session
upload_root: 上传文件根目录(如 ./data/uploads)
max_records: 最大保留条数,<= 0 表示不限制
Returns:
实际删除的记录数
"""
if max_records <= 0:
return 0
# 查询当前总记录数
count_result = await db_session.execute(
select(func.count()).select_from(AlarmRecord)
)
total = count_result.scalar() or 0
if total <= max_records:
return 0
# 超出数量
overflow = total - max_records
# 查询最早的 overflow 条记录(按 created_at 升序)
stmt = (
select(AlarmRecord)
.order_by(asc(AlarmRecord.created_at)) # type: ignore
.limit(overflow)
)
result = await db_session.execute(stmt)
old_records = result.scalars().all()
deleted_count = 0
for record in old_records:
# 清理关联的视频文件目录
if record.video_file:
_delete_video_dir(upload_root, record.video_file)
await db_session.delete(record)
deleted_count += 1
await db_session.commit()
if deleted_count > 0:
logger.info(
f"[AlarmTrim] 已清理 {deleted_count} 条告警记录 "
f"(保留最新 {max_records} 条,原共 {total} 条)"
)
return deleted_count
def _delete_video_dir(upload_root: str, video_id: str) -> None:
"""
删除告警关联的视频文件目录
视频存储路径: {upload_root}/aibox_sophon_adapter/{video_id}/
Args:
upload_root: 上传根目录
video_id: 视频唯一标识(VideoId)
"""
video_dir = os.path.join(upload_root, "aibox_sophon_adapter", video_id)
if not os.path.isdir(video_dir):
return
try:
shutil.rmtree(video_dir)
logger.debug(f"[AlarmTrim] 已删除视频目录: {video_dir}")
except OSError as e:
logger.warning(f"[AlarmTrim] 删除视频目录失败 [{video_dir}]: {e}")