Files
telegram-helper-bot/database/base.py
2026-02-01 22:49:25 +03:00

116 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
from typing import Optional
import aiosqlite
from logs.custom_logger import logger
class DatabaseConnection:
"""Базовый класс для работы с базой данных."""
def __init__(self, db_path: str):
self.db_path = os.path.abspath(db_path)
self.logger = logger
self.logger.info(f'Инициация базы данных: {self.db_path}')
async def _get_connection(self):
"""Получение асинхронного соединения с базой данных."""
try:
conn = await aiosqlite.connect(self.db_path)
# Включаем поддержку внешних ключей
await conn.execute("PRAGMA foreign_keys = ON")
# Включаем WAL режим для лучшей производительности
await conn.execute("PRAGMA journal_mode = WAL")
await conn.execute("PRAGMA synchronous = NORMAL")
await conn.execute("PRAGMA cache_size = 10000")
await conn.execute("PRAGMA temp_store = MEMORY")
return conn
except Exception as e:
self.logger.error(f"Ошибка при получении соединения: {e}")
raise
async def _execute_query(self, query: str, params: tuple = ()):
"""Выполнение запроса с автоматическим закрытием соединения."""
conn = None
try:
conn = await self._get_connection()
result = await conn.execute(query, params)
await conn.commit()
return result
except Exception as e:
self.logger.error(f"Ошибка при выполнении запроса: {e}")
raise
finally:
if conn:
await conn.close()
async def _execute_query_with_result(self, query: str, params: tuple = ()):
"""Выполнение запроса с результатом и автоматическим закрытием соединения."""
conn = None
try:
conn = await self._get_connection()
result = await conn.execute(query, params)
# Получаем все результаты сразу, чтобы можно было закрыть соединение
rows = await result.fetchall()
return rows
except Exception as e:
self.logger.error(f"Ошибка при выполнении запроса: {e}")
raise
finally:
if conn:
await conn.close()
async def _execute_transaction(self, queries: list):
"""Выполнение транзакции с несколькими запросами."""
conn = None
try:
conn = await self._get_connection()
for query, params in queries:
await conn.execute(query, params)
await conn.commit()
except Exception as e:
if conn:
await conn.rollback()
self.logger.error(f"Ошибка при выполнении транзакции: {e}")
raise
finally:
if conn:
await conn.close()
async def check_database_integrity(self):
"""Проверяет целостность базы данных и очищает WAL файлы."""
conn = None
try:
conn = await self._get_connection()
result = await conn.execute("PRAGMA integrity_check")
integrity_result = await result.fetchone()
if integrity_result and integrity_result[0] == "ok":
self.logger.info("Проверка целостности базы данных прошла успешно")
await conn.execute("PRAGMA wal_checkpoint(TRUNCATE)")
self.logger.info("WAL файлы очищены")
else:
self.logger.warning(f"Проблемы с целостностью базы данных: {integrity_result}")
except Exception as e:
self.logger.error(f"Ошибка при проверке целостности базы данных: {e}")
raise
finally:
if conn:
await conn.close()
async def cleanup_wal_files(self):
"""Очищает WAL файлы и переключает на DELETE режим для предотвращения проблем с I/O."""
conn = None
try:
conn = await self._get_connection()
await conn.execute("PRAGMA journal_mode=DELETE")
await conn.execute("PRAGMA journal_mode=WAL")
self.logger.info("WAL файлы очищены и режим восстановлен")
except Exception as e:
self.logger.error(f"Ошибка при очистке WAL файлов: {e}")
raise
finally:
if conn:
await conn.close()