66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
|
"""Сервис для управления базой данных."""
|
||
|
|
||
|
from pathlib import Path
|
||
|
|
||
|
import aiosqlite
|
||
|
import structlog
|
||
|
from sqlmodel import SQLModel, create_engine
|
||
|
|
||
|
from ..models import AppConfig
|
||
|
|
||
|
logger = structlog.get_logger()
|
||
|
|
||
|
|
||
|
class DatabaseService:
|
||
|
def __init__(self, config: AppConfig) -> None:
|
||
|
self.config = config
|
||
|
self.logger = structlog.get_logger().bind(service="database")
|
||
|
|
||
|
self._sync_engine = create_engine(
|
||
|
config.sync_db_url,
|
||
|
echo=False,
|
||
|
connect_args={"check_same_thread": False},
|
||
|
)
|
||
|
|
||
|
async def initialize_database(self) -> None:
|
||
|
db_path = Path(self.config.db_path)
|
||
|
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||
|
|
||
|
self.logger.info("Создание схемы базы данных", db_path=self.config.db_path)
|
||
|
SQLModel.metadata.create_all(self._sync_engine)
|
||
|
|
||
|
await self._configure_sqlite()
|
||
|
|
||
|
self.logger.info("База данных инициализирована", db_path=self.config.db_path)
|
||
|
|
||
|
async def _configure_sqlite(self) -> None:
|
||
|
async with aiosqlite.connect(self.config.db_path) as conn:
|
||
|
await conn.execute("PRAGMA journal_mode=WAL")
|
||
|
|
||
|
await conn.execute("PRAGMA cache_size=10000")
|
||
|
|
||
|
await conn.execute("PRAGMA synchronous=NORMAL")
|
||
|
|
||
|
await conn.execute("PRAGMA busy_timeout=30000")
|
||
|
|
||
|
await conn.commit()
|
||
|
self.logger.info("SQLite настроен для оптимальной производительности")
|
||
|
|
||
|
async def get_connection(self) -> aiosqlite.Connection:
|
||
|
return await aiosqlite.connect(
|
||
|
self.config.db_path,
|
||
|
timeout=30.0,
|
||
|
)
|
||
|
|
||
|
async def health_check(self) -> bool:
|
||
|
try:
|
||
|
async with self.get_connection() as conn:
|
||
|
await conn.execute("SELECT 1")
|
||
|
return True
|
||
|
except Exception as e:
|
||
|
self.logger.error("Database health check failed", error=str(e))
|
||
|
return False
|
||
|
|
||
|
def close(self) -> None:
|
||
|
self._sync_engine.dispose()
|