""" PostgreSQL Database Service """ import asyncpg from typing import Optional, Dict, Any, List from ..config import settings import logging logger = logging.getLogger(__name__) class DatabaseService: """Сервис для работы с PostgreSQL""" def __init__(self): self.pool: Optional[asyncpg.Pool] = None async def connect(self): """Создает пул подключений к PostgreSQL""" try: self.pool = await asyncpg.create_pool( host=settings.postgres_host, port=settings.postgres_port, database=settings.postgres_db, user=settings.postgres_user, password=settings.postgres_password, min_size=5, max_size=20, command_timeout=60 ) logger.info(f"✅ PostgreSQL connected: {settings.postgres_host}:{settings.postgres_port}/{settings.postgres_db}") except Exception as e: logger.error(f"❌ PostgreSQL connection error: {e}") raise async def disconnect(self): """Закрывает пул подключений""" if self.pool: await self.pool.close() logger.info("PostgreSQL pool closed") async def execute(self, query: str, *args) -> str: """Выполняет SQL запрос без возврата данных""" async with self.pool.acquire() as conn: return await conn.execute(query, *args) async def fetch_one(self, query: str, *args) -> Optional[Dict[str, Any]]: """Возвращает одну запись""" async with self.pool.acquire() as conn: row = await conn.fetchrow(query, *args) return dict(row) if row else None async def fetch_all(self, query: str, *args) -> List[Dict[str, Any]]: """Возвращает все записи""" async with self.pool.acquire() as conn: rows = await conn.fetch(query, *args) return [dict(row) for row in rows] async def fetch_val(self, query: str, *args): """Возвращает одно значение""" async with self.pool.acquire() as conn: return await conn.fetchval(query, *args) async def health_check(self) -> bool: """Проверка здоровья БД""" try: result = await self.fetch_val("SELECT 1") return result == 1 except Exception as e: logger.error(f"Database health check failed: {e}") return False # Глобальный экземпляр db = DatabaseService()