migrate --list is now read-only

pending() and applied() no longer create the _sqlite_migrations
table or perform the one-way legacy schema upgrade - that now only
happens in apply(). The CLI --list path no longer creates the
database file when it does not exist. applied() results are now
explicitly ordered by insertion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UnLnhsH25Nnv7LHhekUfPd
This commit is contained in:
Claude 2026-07-04 19:10:56 +00:00
commit 30cc95c0a6
No known key found for this signature in database
6 changed files with 67 additions and 15 deletions

View file

@ -3387,13 +3387,19 @@ def migrate(db_path, migrations, stop_before, list_, verbose):
if not migration_sets:
raise click.ClickException("No migrations.py files found")
db = sqlite_utils.Database(db_path)
_register_db_for_cleanup(db)
if list_:
if pathlib.Path(db_path).exists():
db = sqlite_utils.Database(db_path)
else:
# 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)
return
db = sqlite_utils.Database(db_path)
_register_db_for_cleanup(db)
prev_schema = db.schema
if verbose:
click.echo("Migrating {}".format(db_path))

View file

@ -54,14 +54,10 @@ class Migrations:
def pending(self, db: "Database") -> list["Migrations._Migration"]:
"""
Return a list of pending migrations.
This is a read-only operation - it does not write to the database.
"""
self.ensure_migrations_table(db)
already_applied = {
r["name"]
for r in db[self.migrations_table].rows_where(
"migration_set = ?", [self.name]
)
}
already_applied = {migration.name for migration in self.applied(db)}
return [
migration
for migration in self._migrations
@ -70,13 +66,17 @@ class Migrations:
def applied(self, db: "Database") -> list["Migrations._AppliedMigration"]:
"""
Return a list of applied migrations.
Return a list of applied migrations, in the order they were applied.
This is a read-only operation - it does not write to the database.
"""
self.ensure_migrations_table(db)
table = _table(db, self.migrations_table)
if not table.exists():
return []
return [
self._AppliedMigration(name=row["name"], applied_at=row["applied_at"])
for row in db[self.migrations_table].rows_where(
"migration_set = ?", [self.name]
for row in table.rows_where(
"migration_set = ?", [self.name], order_by="rowid"
)
]