Skip to main content
Data migration scripts live in backend/scripts/data_migrations/. They handle one-off corrections, backfills, or clean-ups that cannot be expressed as a zero-downtime Alembic migration.

How they run

Recent migrations are wired into the container startup script (backend/scripts/start/app.sh) and run automatically on every deploy, after Alembic migrations are applied. They are idempotent (no-op once the data is corrected) and non-fatal - a failure logs a warning and retries on the next startup. This automatic execution is temporary. Each entry in app.sh is gated by a TODO: Remove this after ~<date> comment and is deleted once existing deployments have had time to upgrade. After that point the script is no longer invoked on startup. The practical consequence: if you upgrade Open Wearables long after a migration shipped, the corresponding script may already have been removed from app.sh and will not run automatically. In that case, run it manually (see below). Scripts that were never added to app.sh must always be run manually.

Prerequisites

The scripts import from the app package and connect to the database via the environment variables in backend/config/.env. You need:
  • Docker Compose services running (docker compose up -d)
  • The app container healthy (check with docker compose ps)
  • A database with the latest Alembic migrations applied (docker compose exec app uv run alembic upgrade head)

Running a script

All scripts are run inside the app container using uv run:

Dry run first

Every script supports a --dry-run flag. Always run it first — it prints the rows that would be affected without making any changes:

Apply changes

Once satisfied with the dry-run output, run without the flag:
Scripts write directly to the database. There is no automatic rollback. Take a database snapshot before running against production.