Enhance database connection handling in BotDB class with error checking for file existence and access permissions. Implement methods for database integrity checks and WAL file cleanup. Update database initialization to use absolute project path for improved reliability.

This commit is contained in:
2025-08-26 19:33:11 +03:00
parent 86773cfe20
commit 62af3b73c6
3 changed files with 240 additions and 10 deletions

152
database/fix_database.py Normal file
View File

@@ -0,0 +1,152 @@
#!/usr/bin/env python3
"""
Скрипт для диагностики и исправления проблем с базой данных Telegram бота.
"""
import os
import sys
import sqlite3
from pathlib import Path
def check_database_file(db_path):
"""Проверяет состояние файла базы данных."""
print(f"Проверка файла: {db_path}")
if not os.path.exists(db_path):
print(f"❌ Файл базы данных не найден: {db_path}")
return False
# Проверяем права доступа
if not os.access(db_path, os.R_OK | os.W_OK):
print(f"❌ Нет прав доступа к файлу: {db_path}")
return False
# Проверяем размер файла
file_size = os.path.getsize(db_path)
print(f"✅ Размер файла: {file_size} байт")
return True
def check_wal_files(db_path):
"""Проверяет WAL файлы."""
db_dir = os.path.dirname(db_path)
db_name = os.path.basename(db_path)
base_name = os.path.splitext(db_name)[0]
wal_file = os.path.join(db_dir, f"{base_name}.db-wal")
shm_file = os.path.join(db_dir, f"{base_name}.db-shm")
print(f"\nПроверка WAL файлов:")
if os.path.exists(wal_file):
wal_size = os.path.getsize(wal_file)
print(f"✅ WAL файл найден: {wal_file} ({wal_size} байт)")
else:
print(f" WAL файл не найден: {wal_file}")
if os.path.exists(shm_file):
shm_size = os.path.getsize(shm_file)
print(f"✅ SHM файл найден: {shm_file} ({shm_size} байт)")
else:
print(f" SHM файл не найден: {shm_file}")
return wal_file, shm_file
def test_database_connection(db_path):
"""Тестирует подключение к базе данных."""
print(f"\nТестирование подключения к базе данных...")
try:
conn = sqlite3.connect(db_path, timeout=10.0)
cursor = conn.cursor()
# Проверяем версию SQLite
cursor.execute("SELECT sqlite_version()")
version = cursor.fetchone()[0]
print(f"✅ SQLite версия: {version}")
# Проверяем таблицы
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
tables = cursor.fetchall()
print(f"✅ Найдено таблиц: {len(tables)}")
# Проверяем целостность
cursor.execute("PRAGMA integrity_check")
integrity = cursor.fetchone()[0]
if integrity == "ok":
print("✅ Целостность базы данных: OK")
else:
print(f"⚠️ Проблемы с целостностью: {integrity}")
conn.close()
return True
except sqlite3.Error as e:
print(f"❌ Ошибка SQLite: {e}")
return False
except Exception as e:
print(f"❌ Неожиданная ошибка: {e}")
return False
def cleanup_wal_files(db_path):
"""Очищает WAL файлы."""
print(f"\nОчистка WAL файлов...")
try:
conn = sqlite3.connect(db_path, timeout=10.0)
cursor = conn.cursor()
# Переключаем на DELETE режим для очистки WAL
cursor.execute("PRAGMA journal_mode=DELETE")
cursor.execute("PRAGMA journal_mode=WAL")
# Принудительно создаем checkpoint
cursor.execute("PRAGMA wal_checkpoint(TRUNCATE)")
conn.close()
print("✅ WAL файлы очищены")
return True
except Exception as e:
print(f"❌ Ошибка при очистке WAL файлов: {e}")
return False
def main():
"""Основная функция."""
print("🔧 Диагностика базы данных Telegram бота")
print("=" * 50)
# Определяем путь к базе данных
current_dir = os.getcwd()
db_path = os.path.join(current_dir, 'database', 'tg-bot-database.db')
print(f"Текущая директория: {current_dir}")
print(f"Путь к базе данных: {db_path}")
# Проверяем файл базы данных
if not check_database_file(db_path):
print("\n❌ Файл базы данных недоступен. Проверьте права доступа и существование файла.")
return
# Проверяем WAL файлы
wal_file, shm_file = check_wal_files(db_path)
# Тестируем подключение
if not test_database_connection(db_path):
print("\nНе удалось подключиться к базе данных.")
return
# Очищаем WAL файлы
if cleanup_wal_files(db_path):
print("\n✅ База данных проверена и исправлена.")
else:
print("\n⚠️ База данных проверена, но не удалось очистить WAL файлы.")
print("\n📋 Рекомендации:")
print("1. Убедитесь, что у процесса есть права на запись в директорию database/")
print("2. Проверьте свободное место на диске")
print("3. Если проблемы продолжаются, попробуйте перезапустить бота")
print("4. В крайнем случае, создайте резервную копию и пересоздайте базу данных")
if __name__ == "__main__":
main()