Управление движком базы данных

This commit is contained in:
2026-02-23 14:34:52 +07:00
parent 7037e530fe
commit 7fd1ee2d04

116
database/database.py Normal file
View File

@@ -0,0 +1,116 @@
"""
Управление SQLAlchemy движком и сессиями.
"""
from pathlib import Path
from typing import AsyncGenerator
from sqlalchemy.ext.asyncio import (
create_async_engine,
async_sessionmaker,
AsyncSession,
AsyncEngine
)
from configs import settings
from middleware.loggers import logger
from .models import Base
__all__ = ("Database", "get_db")
class Database:
"""
Менеджер SQLAlchemy базы данных.
Attributes:
engine: Async движок SQLAlchemy
session_factory: Фабрика сессий
"""
def __init__(self, db_path: str = settings.DATABASE_PATH):
"""
Args:
db_path: Путь к SQLite файлу
"""
# Создаём директорию если не существует
db_file = Path(db_path)
db_file.parent.mkdir(parents=True, exist_ok=True)
# SQLite URL для async
db_url = f"sqlite+aiosqlite:///{db_path}"
# Создаём async движок
self.engine: AsyncEngine = create_async_engine(
db_url,
echo=False, # Логирование SQL запросов (False для прода)
future=True,
pool_pre_ping=True, # Проверка соединения
)
# Фабрика сессий
self.session_factory = async_sessionmaker(
self.engine,
class_=AsyncSession,
expire_on_commit=False,
)
logger.info(
f"SQLAlchemy инициализирован: {db_path}",
log_type="DATABASE"
)
async def init(self) -> None:
"""Создаёт все таблицы в БД"""
try:
async with self.engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
logger.info(
"Таблицы базы данных созданы",
log_type="DATABASE"
)
except Exception as e:
logger.error(
f"Ошибка создания таблиц: {e}",
log_type="DATABASE"
)
raise
async def close(self) -> None:
"""Закрывает соединения с БД"""
await self.engine.dispose()
logger.info("База данных закрыта", log_type="DATABASE")
def get_session(self) -> AsyncGenerator[AsyncSession, None]:
"""
Создаёт новую сессию (контекстный менеджер).
Usage:
async with db.get_session() as session:
result = await session.execute(select(BanWord))
words = result.scalars().all()
Yields:
AsyncSession: Сессия для работы с БД
"""
return self.session_factory()
# Глобальный экземпляр
_db_instance: Database | None = None
def get_db(db_path: str = settings.DATABASE_PATH) -> Database:
"""
Возвращает глобальный экземпляр Database (Singleton).
Args:
db_path: Путь к БД (используется только при первом вызове)
Returns:
Database: Экземпляр базы данных
"""
global _db_instance
if _db_instance is None:
_db_instance = Database(db_path)
return _db_instance