62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
from sqlalchemy.ext.asyncio import AsyncSession
|
||
from sqlalchemy.exc import IntegrityError
|
||
from asyncpg.exceptions import UniqueViolationError
|
||
import logging
|
||
|
||
from app.models.call_event import CallEvent
|
||
from app.core.exceptions import CallEventAlreadyExistsError, DatabaseError
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
async def create_call_event(db: AsyncSession, event_data: dict) -> CallEvent:
|
||
"""Создать новое событие звонка в БД
|
||
|
||
Args:
|
||
db: Async сессия базы данных
|
||
event_data: Данные события звонка
|
||
|
||
Returns:
|
||
CallEvent: Созданное событие
|
||
|
||
Raises:
|
||
CallEventAlreadyExistsError: Если событие с таким call_session_id уже существует
|
||
DatabaseError: При других ошибках БД
|
||
"""
|
||
try:
|
||
call_event = CallEvent(**event_data)
|
||
db.add(call_event)
|
||
await db.commit()
|
||
await db.refresh(call_event)
|
||
|
||
logger.info(
|
||
f"Call event created successfully",
|
||
extra={
|
||
"call_session_id": call_event.call_session_id,
|
||
"employee_id": call_event.employee_id
|
||
}
|
||
)
|
||
|
||
return call_event
|
||
|
||
except IntegrityError as e:
|
||
await db.rollback()
|
||
|
||
# Проверяем, является ли это ошибкой уникальности call_session_id
|
||
if isinstance(e.orig, UniqueViolationError):
|
||
call_session_id = event_data.get("call_session_id")
|
||
logger.warning(
|
||
f"Duplicate call event detected",
|
||
extra={"call_session_id": call_session_id}
|
||
)
|
||
raise CallEventAlreadyExistsError(call_session_id)
|
||
|
||
# Другие ошибки целостности
|
||
logger.error(f"Database integrity error: {str(e)}")
|
||
raise DatabaseError(f"Failed to create call event: {str(e)}")
|
||
|
||
except Exception as e:
|
||
await db.rollback()
|
||
logger.error(f"Unexpected error creating call event: {str(e)}", exc_info=True)
|
||
raise DatabaseError(f"Unexpected database error: {str(e)}")
|