Make all migrations idempotent #55

Open
padreug wants to merge 1 commit from fix/idempotent-migrations into main
Owner

First PR of the refactor series from the 2026-06 code review (findings #3/#12).

The migration version bump lands in the core dbversions table while the DDL lands in ext_libra — the two writes are not atomic. A failed bump re-runs the whole migration on next boot; a bare CREATE/ALTER/INSERT then crashes the extension until manual dbversions surgery.

Changes:

  • CREATE TABLE / CREATE INDEXIF NOT EXISTS throughout
  • ALTER TABLE ADD COLUMN_alter_add_column_safe (same swallow pattern as the events/withdraw fork migrations)
  • Seed INSERTs (default accounts, virtual parents, default roles) → ON CONFLICT (name) DO NOTHING

Tests: new tests/test_migrations.py runs the chain twice against a fresh SQLite DB (full-chain rerun + per-migration rerun). Both tests were verified to FAIL against the previous migrations and pass now. Full suite: 153 passed, 3 skipped, 8 xfailed.

🤖 Generated with Claude Code

First PR of the refactor series from the 2026-06 code review (findings #3/#12). The migration version bump lands in the core `dbversions` table while the DDL lands in `ext_libra` — the two writes are not atomic. A failed bump re-runs the whole migration on next boot; a bare CREATE/ALTER/INSERT then crashes the extension until manual dbversions surgery. Changes: - `CREATE TABLE` / `CREATE INDEX` → `IF NOT EXISTS` throughout - `ALTER TABLE ADD COLUMN` → `_alter_add_column_safe` (same swallow pattern as the events/withdraw fork migrations) - Seed INSERTs (default accounts, virtual parents, default roles) → `ON CONFLICT (name) DO NOTHING` Tests: new `tests/test_migrations.py` runs the chain twice against a fresh SQLite DB (full-chain rerun + per-migration rerun). Both tests were verified to FAIL against the previous migrations and pass now. Full suite: 153 passed, 3 skipped, 8 xfailed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The migration version bump lands in the core dbversions table while
the DDL lands in ext_libra — the two writes are not atomic. A failed
bump re-runs the whole migration on next boot; bare
CREATE/ALTER/INSERT then crashes the extension until manual
dbversions surgery.

- CREATE TABLE / CREATE INDEX -> IF NOT EXISTS
- ALTER TABLE ADD COLUMN -> _alter_add_column_safe (same swallow
  pattern as the events/withdraw fork migrations)
- seed INSERTs (default accounts, virtual parents, default roles) ->
  ON CONFLICT (name) DO NOTHING

Tests run the chain twice against a fresh SQLite DB (full-chain rerun
and per-migration rerun); both fail against the previous migrations.

Addresses CODE-REVIEW-2026-06 findings #3 and #12.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/idempotent-migrations:fix/idempotent-migrations
git switch fix/idempotent-migrations

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff fix/idempotent-migrations
git switch fix/idempotent-migrations
git rebase main
git switch main
git merge --ff-only fix/idempotent-migrations
git switch fix/idempotent-migrations
git rebase main
git switch main
git merge --no-ff fix/idempotent-migrations
git switch main
git merge --squash fix/idempotent-migrations
git switch main
git merge --ff-only fix/idempotent-migrations
git switch main
git merge fix/idempotent-migrations
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/libra!55
No description provided.