> ## Documentation Index
> Fetch the complete documentation index at: https://openwearables.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Migrations

> One-off scripts for backfilling or correcting data in the database. Some run automatically on startup for a limited time; all can be run manually.

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.

<Note>
  This page covers **how** to run the scripts. The rationale for each individual migration — the problem it fixes and what it changes, plus any relevant details such as conflict handling or idempotency — lives in the module docstring at the top of the corresponding script in `backend/scripts/data_migrations/`. Read that before running one.
</Note>

## 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`:

```bash theme={null}
docker compose exec app uv run python scripts/data_migrations/<script_name>.py [options]
```

### 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:

```bash theme={null}
docker compose exec app uv run python scripts/data_migrations/<script_name>.py --dry-run
```

### Apply changes

Once satisfied with the dry-run output, run without the flag:

```bash theme={null}
docker compose exec app uv run python scripts/data_migrations/<script_name>.py
```

<Warning>
  Scripts write directly to the database. There is no automatic rollback. Take a database snapshot before running against production.
</Warning>
