Enhance bot functionality and refactor database interactions

- Added `ca-certificates` installation to Dockerfile for improved network security.
- Updated health check command in Dockerfile to include better timeout handling.
- Refactored `run_helper.py` to implement proper signal handling and logging during shutdown.
- Transitioned database operations to an asynchronous model in `async_db.py`, improving performance and responsiveness.
- Updated database schema to support new foreign key relationships and optimized indexing for better query performance.
- Enhanced various bot handlers to utilize async database methods, improving overall efficiency and user experience.
- Removed obsolete database and fix scripts to streamline the project structure.
This commit is contained in:
2025-09-02 18:22:02 +03:00
parent 013892dcb7
commit 1c6a37bc12
59 changed files with 5682 additions and 4204 deletions

114
database/base.py Normal file
View File

@@ -0,0 +1,114 @@
import os
import aiosqlite
from typing import Optional
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()