All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
--allow-out-of-order on migrate and redo (and ?allow_out_of_order on Migrator.run/run_or_error/redo and the plans): apply a pending migration that is older than the newest applied one - the situation after merging a branch whose migrations carry older timestamps - with a logged warning, instead of failing with OutOfOrder. The strict failure remains the default.redo --dry-run (and Migrator.redo_plan): preview what redo would roll back and re-apply without touching the database.migrate --dry-run and rollback --dry-run now run the same drift validation as the real commands, so a plan can no longer promise migrations that the real run immediately refuses with ChecksumMismatch or AppliedFileMissing.-journal/-wal/-shm sidecar files, so a stale sidecar left by an unclean close cannot be found by a future database recreated at the same path.$$ inside a PostgreSQL identifier (such as a$$b, one identifier token) as a dollar-quote opener that would swallow the following statement separators.status output also masks passwords passed as URL query parameters (?password=, ?sslpassword=), not just the userinfo password.COMMIT is reported directly instead of issuing a ROLLBACK against the already-ended transaction, which could fail too and replace the real error with a misleading "inconsistent state" report.run/rollback/redo and the dry-run plans read the migrations directory and the tracking table once per invocation (a shared snapshot) instead of re-reading them for each check, which also removes the window where the two reads could disagree.Connection.with_db and Connection.get_port helpers.migrate and every command that ensures the tracking table no longer fail on MySQL. ensure_migrations_table ran ALTER TABLE ... ADD COLUMN IF NOT EXISTS, a MariaDB-only extension that MySQL rejects as a syntax error, so migra was effectively broken against mysql:// servers. The table is now created with the checksum column directly, with no post-creation backfill.status and --dry-run no longer take the wrong path when another database (MySQL/MariaDB) or schema (PostgreSQL) on the same server has a schema_migrations table. table_exists now resolves on the connection's own database and search_path - PostgreSQL via to_regclass, MySQL/MariaDB via DATABASE() - instead of matching by table name across the whole server.--table (an empty or extra segment such as public., a..b, or a.b.c) is now rejected with a clear validation error instead of surfacing later as a database parse error.redo command's --help text and the README's redo one-liner now describe its actual behavior: roll back the last migration(s), then run all pending migrations.generate no longer creates a migration file that breaks discovery. An empty or otherwise invalid name (anything outside letters, digits, and underscores) is now rejected, as is a name already used by an existing migration. Such files were previously written - and reported as created - then made every later migrate, status, and rollback fail until removed by hand.generate now reports the duplicate and exits instead of writing a second file with the same version (which discovery would then reject).Types.VersionTaken error variant, returned by generate when the version it would assign is already used by a migration on disk.migra.engine library. Its modules (runner, SQL parser, dialect, discovery, migration, connection) are now private modules of migra, so code that reached into Migra_engine.* must use the public Migra.* API. The CLI and the Migra.Database / Migra.Migrator / Migra.Types / Migra.Logging facades are unchanged.Migra.Migrator.rollback_strategy is its own type rather than an alias of the engine's strategy type.migra no longer installs a Logs reporter or sets the level; call Migra.Logging.setup () to opt in (the CLI does this at startup).FileNotFound, DatabaseNotFound, and TransactionFailed, and added WriteError for migration-file write failures.generate honors the --dir option (and Migrator.generate ~migrations_dir).init/setup/drop/reset) accept sqlite3:path URLs - the documented form, and what sqlite3:// normalizes to - which previously failed with "invalid path format".mysql:// connection URLs are rewritten to the mariadb:// scheme the Caqti driver registers, so they connect instead of reporting a missing driver.DELIMITER directive is honored only for MySQL/MariaDB, so SQL beginning with the word "delimiter" is not misparsed on other dialects.$1$), PostgreSQL E'...' escape strings, and backslash escapes inside MySQL double-quoted strings.status and migrate --dry-run are read-only and no longer create the migrations-tracking table.rollback selectors (--all with --to or --step) are rejected instead of silently ignored.COMMIT/BEGIN in a migration's own SQL ends Migra's wrapping transaction early, and on PostgreSQL a statement that returns rows (e.g. SELECT setval(...)) is rejected. See the Transactions notes in the README.rollback and redo now validate applied migrations against the files on disk before running and return Error on drift (a modified or missing applied migration), just like migrate. Previously they could roll back using modified down SQL or silently skip a migration whose file was gone.status now includes an applied migration whose file is missing (shown as (migration file missing)) instead of hiding it and understating the applied count.create_database/drop_database) now quote and escape the database identifier in the generated DDL, so PostgreSQL names such as my-db work and MariaDB names containing backticks are handled safely.First stable release.
migrate refuses to run if an already-applied migration was modified (ChecksumMismatch) or its file went missing (AppliedFileMissing).OutOfOrder).--table / Migrator.make ~table.redo command and Migrator.redo - roll back the last migration(s) and re-apply.--dry-run for migrate and rollback - preview without changing the database.--database-url flag - overrides the DATABASE_URL environment variable.Migra.Migrator (run/run_or_error/rollback/redo/status/generate, with ?on_event progress callbacks) and Migra.Database (lifecycle + URL helpers) form the public API; the implementation lives in the internal migra.engine library.Migra.Migrator.run_or_error - a fail-fast wrapper around run for the migrate-on-startup path: a migration whose SQL fails is returned as Error (MigrationError (ExecutionFailed ...)) rather than Ok with failure_count > 0.DELIMITER for MySQL/MariaDB routines, line/block comments, and literal $/? in statements.*****) in status output and never printed in clear._<description>.sql; malformed migration-shaped files are reported instead of silently skipped.Migrator.run/rollback return Error only when migrations could not run; per-migration SQL failures surface as Ok with failure_count > 0 (see Migrator.succeeded).