migrate --list is read-only with legacy sqlite-migrate classes too

The docs promise --list will not create the database file or the
_sqlite_migrations table, but legacy sqlite_migrate.Migrations classes
create the table (in the legacy schema) from their pending()/applied()
methods. The listing now runs inside a transaction that is rolled back,
keeping --list read-only regardless of what the migration class does.

Refs https://github.com/simonw/sqlite-utils/issues/769#issuecomment-4900034150

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Simon Willison 2026-07-06 21:58:52 -07:00
commit 93640a7dde
3 changed files with 29 additions and 1 deletions

View file

@ -3434,7 +3434,14 @@ def migrate(db_path, migrations, stop_before, list_, verbose):
# Listing is read-only - don't create the database file
db = sqlite_utils.Database(memory=True)
_register_db_for_cleanup(db)
_display_migration_list(db, migration_sets)
# Legacy sqlite-migrate classes create the migrations table from
# their pending()/applied() methods - run the listing inside a
# transaction and roll it back so --list stays read-only
db.begin()
try:
_display_migration_list(db, migration_sets)
finally:
db.rollback()
return
db = sqlite_utils.Database(db_path)