Releases: dsincl12/migra
Releases · dsincl12/migra
Release list
2.2.0
CHANGES:
Added
--allow-out-of-orderonmigrateandredo(and?allow_out_of_orderon
Migrator.run/run_or_error/redoand 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 withOutOfOrder. The strict failure remains the
default.redo --dry-run(andMigrator.redo_plan): preview whatredowould roll
back and re-apply without touching the database.
Fixed
migrate --dry-runandrollback --dry-runnow run the same drift
validation as the real commands, so a plan can no longer promise migrations
that the real run immediately refuses withChecksumMismatchor
AppliedFileMissing.- Dropping a SQLite database also deletes its
-journal/-wal/-shmsidecar
files, so a stale sidecar left by an unclean close cannot be found by a
future database recreated at the same path. - The SQL splitter no longer misreads a
$$inside a PostgreSQL identifier
(such asa$$b, one identifier token) as a dollar-quote opener that would
swallow the following statement separators. statusoutput also masks passwords passed as URL query parameters
(?password=,?sslpassword=), not just the userinfo password.- A failed
COMMITis reported directly instead of issuing aROLLBACK
against the already-ended transaction, which could fail too and replace the
real error with a misleading "inconsistent state" report.
Changed
run/rollback/redoand 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.- Removed the unused internal
Connection.with_dbandConnection.get_port
helpers.
2.1.1
CHANGES:
Fixed
migrateand every command that ensures the tracking table no longer fail
on MySQL.ensure_migrations_tableranALTER TABLE ... ADD COLUMN IF NOT EXISTS, a MariaDB-only extension that MySQL rejects as a syntax error, so
migra was effectively broken againstmysql://servers. The table is now
created with thechecksumcolumn directly, with no post-creation backfill.statusand--dry-runno longer take the wrong path when another database
(MySQL/MariaDB) or schema (PostgreSQL) on the same server has a
schema_migrationstable.table_existsnow resolves on the connection's
own database and search_path - PostgreSQL viato_regclass, MySQL/MariaDB
viaDATABASE()- instead of matching by table name across the whole server.- An invalid migrations-table name passed to
--table(an empty or extra
segment such aspublic.,a..b, ora.b.c) is now rejected with a clear
validation error instead of surfacing later as a database parse error. - The
redocommand's--helptext and the README'sredoone-liner now
describe its actual behavior: roll back the last migration(s), then run all
pending migrations.
2.1.0
CHANGES:
Fixed
generateno 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
latermigrate,status, androllbackfail until removed by hand.- Two migrations generated in the same second no longer collide silently.
Version stamps have one-second resolution, sogeneratenow reports the
duplicate and exits instead of writing a second file with the same version
(which discovery would then reject).
Added
Types.VersionTakenerror variant, returned bygeneratewhen the version it
would assign is already used by a migration on disk.
2.0.0
CHANGES:
Changed (breaking)
- The engine is no longer shipped as a separate public
migra.enginelibrary.
Its modules (runner, SQL parser, dialect, discovery, migration, connection)
are now private modules ofmigra, so code that reached intoMigra_engine.*
must use the publicMigra.*API. The CLI and theMigra.Database/
Migra.Migrator/Migra.Types/Migra.Loggingfacades are unchanged. Migra.Migrator.rollback_strategyis its own type rather than an alias of the
engine's strategy type.- Logging is no longer configured as a side effect of loading the library.
Linkingmigrano longer installs aLogsreporter or sets the level; call
Migra.Logging.setup ()to opt in (the CLI does this at startup). - Removed the unused error variants
FileNotFound,DatabaseNotFound, and
TransactionFailed, and addedWriteErrorfor migration-file write failures.
Added
generatehonors the--diroption (andMigrator.generate ~migrations_dir).
Fixed
- The database lifecycle commands (
init/setup/drop/reset) accept
sqlite3:pathURLs - the documented form, and whatsqlite3://normalizes
to - which previously failed with "invalid path format". mysql://connection URLs are rewritten to themariadb://scheme the Caqti
driver registers, so they connect instead of reporting a missing driver.- A connection failure that merely mentions "not found" (a missing host, role,
or database) is no longer misreported as a missing database driver. - Migration version stamps are generated in UTC, so they no longer depend on the
developer's timezone or DST. - The
DELIMITERdirective is honored only for MySQL/MariaDB, so SQL beginning
with the word "delimiter" is not misparsed on other dialects. - The SQL splitter handles digit-led dollar tags (
$1$), PostgreSQLE'...'
escape strings, and backslash escapes inside MySQL double-quoted strings. - Each migration file is read once when applied, so the recorded checksum always
matches the SQL that ran. statusandmigrate --dry-runare read-only and no longer create the
migrations-tracking table.- Conflicting
rollbackselectors (--allwith--toor--step) are
rejected instead of silently ignored. - A migration-file write failure is reported as a write error (no longer a read
error) and no longer leaks the file descriptor. - Removed a doubled blank line from applied/rolled-back migration output.
Known limitations
- Migration atomicity has per-dialect limits: MySQL/MariaDB DDL implicitly
commits, aCOMMIT/BEGINin 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.
1.0.1
CHANGES:
Fixed
rollbackandredonow validate applied migrations against the files on
disk before running and returnErroron drift (a modified or missing
applied migration), just likemigrate. Previously they could roll back
using modified down SQL or silently skip a migration whose file was gone.statusnow includes an applied migration whose file is missing (shown as
(migration file missing)) instead of hiding it and understating the applied
count.- Database lifecycle commands (
create_database/drop_database) now quote and
escape the database identifier in the generated DDL, so PostgreSQL names such
asmy-dbwork and MariaDB names containing backticks are handled safely.
1.0.0
CHANGES:
First stable release.
Added
- Checksums & validation - each applied migration's file checksum is
recorded;migraterefuses to run if an already-applied migration was
modified (ChecksumMismatch) or its file went missing (AppliedFileMissing). - Out-of-order detection - adding a migration older than the latest applied
one is rejected (OutOfOrder). - Configurable migrations table via
--table/Migrator.make ~table. redocommand andMigrator.redo- roll back the last migration(s) and
re-apply.--dry-runformigrateandrollback- preview without changing the
database.--database-urlflag - overrides theDATABASE_URLenvironment variable.- Library facade -
Migra.Migrator
(run/run_or_error/rollback/redo/status/generate, with?on_eventprogress
callbacks) andMigra.Database(lifecycle + URL helpers) form the public API;
the implementation lives in the internalmigra.enginelibrary. Migra.Migrator.run_or_error- a fail-fast wrapper aroundrunfor the
migrate-on-startup path: a migration whose SQL fails is returned asError
(MigrationError (ExecutionFailed ...)) rather thanOkwith
failure_count > 0.- Arbitrary SQL support: dollar-quoted bodies,
DELIMITERfor MySQL/MariaDB
routines, line/block comments, and literal$/?in statements.
Changed
- Credentials are masked (
*****) instatusoutput and never printed in clear. - Stricter migration filenames: exactly 14 digits then
_<description>.sql;
malformed migration-shaped files are reported instead of silently skipped. Migrator.run/rollbackreturnErroronly when migrations could not run;
per-migration SQL failures surface asOkwithfailure_count > 0(see
Migrator.succeeded).
Fixed
- Connections are always closed (no leak), even on error paths.
- The admin connection URL preserves passwords, query parameters, and IPv6 hosts.
- Duplicate migration versions are detected and rejected.
Known limitations
- On MySQL/MariaDB, DDL statements implicitly commit and cannot be rolled back,
so a multi-statement DDL migration is not atomic there. Keep MySQL/MariaDB
migrations to a single DDL change each. (PostgreSQL and SQLite are fully
transactional, including DDL.)