scripts/data_migrations/backfill_sleep_scores.py
Problem
Thecc39513098b0 Alembic migration added a sleep_record_id foreign key to health_score and deleted all internal sleep scores that were not linked to a specific session (data_source_id IS NULL). This script regenerates scores for any sleep session that no longer has one.
It mirrors the logic of the fill_missing_sleep_scores Celery task but accepts an explicit --days argument so you can backfill further back than the task’s rolling window.
What it does
Finds all non-nap sleep sessions within the lookback window that have no corresponding internal sleep score (matched via thesleep_record_id FK), then computes and saves a score for each using the four-pillar sleep algorithm (duration, stages, consistency, interruptions).
Sessions are matched by sleep_record_id — not by date — so multiple sessions on the same wake date (e.g. from different providers) each get their own score.
Usage
Options
| Flag | Default | Description |
|---|---|---|
--days N | score_backfill_days setting (30) | How many days back to scan for unscored sessions. |
--dry-run | — | Print sessions that would be scored. No changes made. |
Dry run output
Related
This script complements thefill_missing_sleep_scores Celery task, which runs automatically on a schedule to score newly synced sessions. Use this script when you need to backfill beyond the task’s configured window or after a migration that deleted existing scores.
