Table-rebuild migrations cascade-delete children under sqlx 0.8 #155

Closed
opened 2026-08-23 20:59:19 +01:00 by naps62-yolo · 0 comments
Owner

Any migration that rebuilds a parent table in this repo silently cascade-deletes
its children, and the usual guard does not work.

sqlx-sqlite 0.8.6 ignores Migration.no_tx and always begins a transaction in
apply(). PRAGMA foreign_keys = OFF is a no-op inside a transaction, so the
standard SQLite table-rebuild recipe — turn foreign keys off, create the new
table, copy, drop the old, rename — deletes every referencing row when the drop
runs. Dropping episodes takes episode_releases with it.

This already shapes the migrations here: 0014 carries a
movie_releases_backup table for exactly this reason, and #153 abandoned an
otherwise correct CHECK (title <> '') after hitting it.

Options, in rough order of preference:

  • Bump the workspace to sqlx 0.9, which honours -- no-transaction on SQLite,
    and drop the backup-table workaround.
  • Keep 0.8 and write the recipe down in CLAUDE.md so each session does not
    rediscover it — copy children out, rebuild, copy back.

Worth deciding before the next table rebuild rather than during one. Filed with
no milestone: this is workspace tooling, not TV tracking.

Any migration that rebuilds a parent table in this repo silently cascade-deletes its children, and the usual guard does not work. `sqlx-sqlite` 0.8.6 ignores `Migration.no_tx` and always begins a transaction in `apply()`. `PRAGMA foreign_keys = OFF` is a no-op inside a transaction, so the standard SQLite table-rebuild recipe — turn foreign keys off, create the new table, copy, drop the old, rename — deletes every referencing row when the drop runs. Dropping `episodes` takes `episode_releases` with it. This already shapes the migrations here: `0014` carries a `movie_releases_backup` table for exactly this reason, and `#153` abandoned an otherwise correct `CHECK (title <> '')` after hitting it. Options, in rough order of preference: - Bump the workspace to sqlx 0.9, which honours `-- no-transaction` on SQLite, and drop the backup-table workaround. - Keep 0.8 and write the recipe down in `CLAUDE.md` so each session does not rediscover it — copy children out, rebuild, copy back. Worth deciding before the next table rebuild rather than during one. Filed with no milestone: this is workspace tooling, not TV tracking.
naps62-yolo added the area/dbtype/choredifficulty/moderate labels 2026-08-23 20:59:19 +01:00
naps62-yolo added this to the Reliability and first run milestone 2026-08-24 17:58:27 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: yolo/arr#155