Загрузка данных
# -*- coding: utf-8 -*-
# modules/data/database_module.py
import sys
import sqlite3
from pathlib import Path
# --- ИСПРАВЛЕННЫЙ ПУТЬ К БАЗЕ ДАННЫХ ---
try:
# Сначала пробуем определить корень от рабочей директории (где лежит main.py)
potential_base = Path.cwd()
# Проверяем, находимся ли мы внутри структуры Dozor
if "Dozor" not in str(potential_base):
# Если запущено откуда-то еще, поднимаемся на 3 уровня вверх
# от текущего файла (__file__), чтобы попасть в E:\Dozor
BASE_DIR = Path(__file__).resolve().parents[3]
else:
BASE_DIR = potential_base
DB_FOLDER = BASE_DIR / "db"
DB_PATH = DB_FOLDER / "database.db"
except Exception as e:
print(f"[FATAL] Не удалось вычислить путь к базе данных: {e}")
sys.exit(1)
def get_db_connection():
"""Создает соединение с БД, создавая файл и папку при необходимости."""
try:
# Создаем папку db, если ее нет по правильному пути
if not DB_FOLDER.exists():
print(f"[ACTION] Создаю папку для базы: {DB_FOLDER}")
DB_FOLDER.mkdir(parents=True, exist_ok=True)
conn = sqlite3.connect(DB_PATH)
conn.execute("PRAGMA foreign_keys = ON;")
return conn
except Exception as e:
print(f"[FATAL] Не удалось подключиться к БД по пути {DB_PATH}. Ошибка: {e}")
raise
def init_database():
"""Инициализирует структуру таблиц и заполняет тестовыми данными."""
conn = get_db_connection()
cursor = conn.cursor()
try:
# --- СОЗДАНИЕ ТАБЛИЦ ---
# Таблица groups
cursor.execute('''
CREATE TABLE IF NOT EXISTS groups (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
code TEXT NOT NULL UNIQUE,
kov REAL DEFAULT 0.0,
gain_kov REAL DEFAULT 0.0
)
''')
# Таблица indicators
cursor.execute('''
CREATE TABLE IF NOT EXISTS indicators (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
code TEXT NOT NULL UNIQUE,
group_code TEXT NOT NULL,
kov REAL DEFAULT 0.0,
total_kov REAL DEFAULT 0.0,
FOREIGN KEY (group_code) REFERENCES groups(code) ON DELETE CASCADE
)
''')
# Таблица metrics
cursor.execute('''
CREATE TABLE IF NOT EXISTS metrics (
id INTEGER PRIMARY KEY AUTOINCREMENT,
group_id INTEGER NOT NULL,
indicator_id INTEGER NOT NULL,
row INTEGER NOT NULL,
col INTEGER NOT NULL,
value REAL DEFAULT 0.0,
FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE,
FOREIGN KEY (indicator_id) REFERENCES indicators(id) ON DELETE CASCADE
)
''')
conn.commit()
# --- ЗАПОЛНЕНИЕ ТЕСТОВЫМИ ДАННЫМИ ---
# Проверяем, есть ли уже группы (если база не пуста - ничего не делаем)
cursor.execute("SELECT COUNT(*) FROM groups")
count = cursor.fetchone()[0]
if count == 0:
print("[INFO] База данных пуста. Заполняю тестовыми данными...")
# Данные для групп
groups_data = [
("Клубы", "KB"),
("Фанаты", "FAN")
]
cursor.executemany("INSERT INTO groups (name, code) VALUES (?, ?)", groups_data)
# Данные для показателей (привязываем по коду группы)
indicators_data = [
# Клубы (KB)
("ЦСКА", "KB-1", "KB", 0.0, 0.0),
("Спартак", "KB-2", "KB", 0.0, 0.0),
("Зенит", "KB-3", "KB", 0.0, 0.0),
# Фанаты (FAN)
("Мужчины", "FAN-1", "FAN", 0.0, 0.0),
("Женщины", "FAN-2", "FAN", 0.0, 0.0),
("Дети", "FAN-3", "FAN", 0.0, 0.0)
]
cursor.executemany(
"INSERT INTO indicators (name, code, group_code, kov, total_kov) VALUES (?, ?, ?, ?, ?)",
indicators_data
)
conn.commit()
print("[SUCCESS] Тестовые данные успешно записаны.")
else:
print("[INFO] База данных уже содержит данные. Пропускаю инициализацию.")
except sqlite3.Error as e:
print(f"[ERROR] Ошибка базы данных: {e}")
if conn:
conn.rollback()
finally:
if conn:
conn.close()
# --- ЗАГЛУШКИ ДЛЯ ЗАПУСКА GUI ---
# Добавлены временно для обхода ошибок импорта при разработке без БД
class Session:
"""Заглушка класса Session. Нужна только для успешного импорта."""
def __init__(self):
pass
def list_groups():
"""
Заглушка вместо реального запроса к БД.
Возвращает тестовые данные в формате кортежей: (id, name).
"""
return [
(1, "Клубы"),
(2, "Фанаты")
]
def get_all_indicators_by_group(group_code):
"""
Заглушка вместо реального запроса к БД по коду группы.
Принимает строку кода ('KB', 'FAN') и возвращает список показателей.
Формат: (id, name)
"""
if group_code == "KB":
return [
(1, "ЦСКА"),
(2, "Спартак"),
(3, "Зенит")
]
elif group_code == "FAN":
return [
(4, "Мужчины"),
(5, "Женщины"),
(6, "Дети")
]
return []
# Автоматический запуск при импорте этого файла (на время разработки)
# Для продакшена лучше вызывать init_database() вручную из главного скрипта
if __name__ == "__main__":
init_database()