# Нормализованное хранение хоккейной статистики Эта сборка сохраняет исходные XML/JSON Stat2TV как `raw_payload`, но дополнительно раскладывает основные данные по отдельным SQL-таблицам PostgreSQL. ## Новые таблицы - `hockey_game_team_statistics` — командная статистика конкретного матча: итог + отдельная строка на каждый период для обеих команд. - `hockey_player_season_statistics` — сезонная статистика игроков и вратарей по турниру. - `hockey_tournament_standing_rows` — нормализованные строки общей таблицы, конференций и дивизионов. - `hockey_tournament_statistic_rows` — нормализованные строки `powerplay` и `rank`. - `hockey_team_season_statistics` — единая сезонная строка команды, собранная из standings + powerplay. Расписание уже хранится нормализованно в `hockey_games` и продолжает обновляться прежним механизмом. ## Что происходит при запуске `database.create_all()` создаёт отсутствующие таблицы без удаления существующих данных. После этого выполняется backfill: если новые нормализованные таблицы ещё пустые, уже сохранённые `raw_payload` разбираются локально и переносятся в новые таблицы без повторного обращения к Stat2TV. ## Автоматическая запись при новых sync - sync карточки матча -> `hockey_game_team_statistics`; - sync players -> `hockey_player_season_statistics`; - sync standings -> `hockey_tournament_standing_rows` + пересборка `hockey_team_season_statistics`; - sync powerplay/rank -> `hockey_tournament_statistic_rows` + пересборка сезонной строки команды для powerplay. ## Проверка базы Общее состояние: ```text GET /api/hockey/database/statistics-status ``` Только один турнир: ```text GET /api/hockey/database/statistics-status?tournament_id=1369 ``` Ответ показывает имя SQL-таблицы, количество строк и время последней синхронизации. Для `powerplay/rank` также возвращается количество строк по каждому `resource_type`. ## Ручной backfill Администратор может повторно разложить сохранённые RAW-данные: ```text POST /api/hockey/database/statistics-backfill ``` Запрос к Stat2TV для этой операции не нужен. ## Безопасность обновления Существующие `raw_payload`, расписание, матчи, составы, события, mapping и vMix-настройки не удаляются. Новые таблицы добавляются поверх текущей схемы. ## Build 31 fix — 2026-08-18 - Исправлена дедупликация команд в `hockey_team_season_statistics`, когда один и тот же клуб повторяется в нескольких секциях `powerplay` XML. - Поддержаны реальные ключи Stat2TV `pp`, `ppgf`, `pp_pct` вместе с прежними `ppo`, `ppg`. - Перед пересборкой сезонной командной статистики удаляются и уже записанные, и pending ORM-строки текущего Session. - В SQLAlchemy включён `hide_parameters=True`: большие XML/JSON payload больше не печатаются в traceback SQL-ошибок. - В консоль добавлены только короткие сообщения об обновлении матчей, игроков, standings, powerplay/rank и backfill.