From ba93ac1970c5385cb45223ba03b6433ec4885707 Mon Sep 17 00:00:00 2001 From: poturaevpetr Date: Tue, 30 Dec 2025 00:25:29 +0500 Subject: [PATCH] add autorestart rec --- apiApp/routers/audio_management_helper.py | 32 ++++++++ apiApp/routers/audio_management_router.py | 99 ++++++++--------------- 2 files changed, 65 insertions(+), 66 deletions(-) create mode 100644 apiApp/routers/audio_management_helper.py diff --git a/apiApp/routers/audio_management_helper.py b/apiApp/routers/audio_management_helper.py new file mode 100644 index 0000000..fd82cd0 --- /dev/null +++ b/apiApp/routers/audio_management_helper.py @@ -0,0 +1,32 @@ +""" +Исправленная версия для проверки Audio без AiConclusion +""" +from sqlalchemy import exists + + +def get_audio_without_conclusion(db, limit=100): + """ + Находит все Audio, у которых нет AiConclusion + + Использует подзапрос через exists, так как AiConclusion - это relationship + """ + # Импортируем модели + from apiApp.database.Audio import Audio + from apiApp.database.AiConclusion import AiConclusion + + # Создаём подзапрос для проверки наличия AiConclusion + subquery = db.query(AiConclusion.audio_id).filter( + AiConclusion.audio_id == Audio.id + ) + + # Находим Audio без AiConclusion + pending_audio = db.query(Audio).filter( + ~exists().where(subquery.exists()) + ).order_by(Audio.index_date.asc()).limit(limit).all() + + # Считаем total + total_pending = db.query(Audio).filter( + ~exists().where(subquery.exists()) + ).count() + + return pending_audio, total_pending diff --git a/apiApp/routers/audio_management_router.py b/apiApp/routers/audio_management_router.py index 5528757..903ba78 100644 --- a/apiApp/routers/audio_management_router.py +++ b/apiApp/routers/audio_management_router.py @@ -1,62 +1,3 @@ -""" -API endpoints для управления аудиофайлами (регистрация и пакетная обработка) -Используется Calls_WEB_Client_main для оркестрации процесса распознавания -""" -from fastapi import APIRouter, HTTPException, Depends, BackgroundTasks -from sqlalchemy.orm import Session -from pydantic import BaseModel -from typing import Optional, List -import os -import logging -from datetime import datetime - -from apiApp.database import get_db -from apiApp.database.Audio import Audio -from apiApp.config import AUDIOFILES_PATH - -logger = logging.getLogger(__name__) -audio_management_router = APIRouter() - - -class AudioRegisterRequest(BaseModel): - """Запрос на регистрацию аудиофайла""" - filename: str - file_path: str # Полный путь к файлу в общей папке audiofiles - - -class AudioProcessAllRequest(BaseModel): - """Запрос на пакетное распознавание""" - limit: int = 100 - - -class AudioRegisterResponse(BaseModel): - """Ответ на регистрацию аудиофайла""" - id: str - filename: str - file_size: int - created_at: datetime - - -@audio_management_router.post("/audio/register", response_model=AudioRegisterResponse, status_code=201) -async def register_audio_file( - request: AudioRegisterRequest, - db: Session = Depends(get_db) -): - """ - Регистрация аудиофайла в БД (без копирования файла) - - Создаёт запись в таблице Audio для файла, который уже находится - в общей папке audiofiles. НЕ копирует файл, только создаёт запись в БД. - - Args: - request: {filename: "in-xxx.wav", file_path: "/app/audiofiles/in-xxx.wav"} - - Returns: - 201 Created + информация о созданной записи - 400 Bad Request если файл уже зарегистрирован - 404 Not Found если файл не существует на диске - """ - try: filename = request.filename file_path = request.file_path @@ -170,16 +111,24 @@ async def process_all_pending_audio( } """ try: + from sqlalchemy import exists + limit = request.limit logger.info(f"🚀 Поиск Audio без AiConclusion (limit={limit})") - # Находим все Audio без AiConclusion + # Находим все Audio без AiConclusion через подзапрос + subquery = db.query(AiConclusion.audio_id).filter( + AiConclusion.audio_id == Audio.id + ) + pending_audio = db.query(Audio).filter( - Audio.AiConclusion == None + ~exists().where(subquery.exists()) ).order_by(Audio.index_date.asc()).limit(limit).all() - total_pending = db.query(Audio).filter(Audio.AiConclusion == None).count() + total_pending = db.query(Audio).filter( + ~exists().where(subquery.exists()) + ).count() if not pending_audio: logger.info("ℹ️ Нет файлов для распознавания") @@ -262,8 +211,14 @@ async def get_pending_audio( Список файлов, ожидающих распознавания """ try: + from sqlalchemy import exists + + subquery = db.query(AiConclusion.audio_id).filter( + AiConclusion.audio_id == Audio.id + ) + pending_audio = db.query(Audio).filter( - Audio.AiConclusion == None + ~exists().where(subquery.exists()) ).order_by(Audio.index_date.asc()).limit(limit).all() files_info = [] @@ -279,7 +234,9 @@ async def get_pending_audio( "exists_on_disk": exists }) - total_pending = db.query(Audio).filter(Audio.AiConclusion == None).count() + total_pending = db.query(Audio).filter( + ~exists().where(subquery.exists()) + ).count() return { "total_pending": total_pending, @@ -304,9 +261,19 @@ async def get_audio_stats(db: Session = Depends(get_db)): Статистика по Audio записям """ try: + from sqlalchemy import exists + total_audio = db.query(Audio).count() - with_conclusion = db.query(Audio).filter(Audio.AiConclusion != None).count() - without_conclusion = db.query(Audio).filter(Audio.AiConclusion == None).count() + + subquery = db.query(AiConclusion.audio_id).filter( + AiConclusion.audio_id == Audio.id + ) + + with_conclusion = db.query(Audio).filter( + exists().where(subquery.exists()) + ).count() + + without_conclusion = total_audio - with_conclusion # Проверяем существование файлов на диске all_audio = db.query(Audio).all()