Skip to main content

migr8

tests vulnerabilities secrets PyPI Python license

An inspectable database migration engine. Oracle is the primary target, PostgreSQL is the second adapter, and SQLite is a supported local-file target within a stated profile.

The tests badge covers the whole suite, including the Oracle and PostgreSQL adapters running against real servers. docs/ACCEPTANCE.md records what each tier proves and which gates are open.

Document What it is for
docs/MANUAL.md Start here. Install, configure, write a migration, run it, recover, diagnose.
docs/SPEC.md The maintained specification: the protocol and its guarantees.
docs/ARCHITECTURE.md Module layering, what each adapter owns, and the standing design positions.
docs/ACCEPTANCE.md What was tested, against which versions, and which gates are open.
docs/ORACLE-CONNECTIONS.md Thin and thick drivers, TNS aliases, proxy authentication, wallets and TLS.
deploy/apple-container/ Running the migration job as a container under Apple's container runtime.

What it does

One ordered TOML manifest defines one migration stream for one database namespace. The database holds an immutable successful prefix and at most one active restartable migration immediately after it. Migrations are SQL or Python, atomic or restartable, with permanent identities and fingerprinted source.

Command surface:

migr8 migrate  [--config PATH] [--manifest PATH] [--recover ID]
migr8 validate [--config PATH] [--manifest PATH] [--json] [--offline] [--baseline PATH]
migr8 status   [--config PATH] [--manifest PATH] [--json]

validate --offline is the plan lint for CI: it checks the manifest, the fingerprints, statement admission and Python compilation with no database, no secret and no namespace, and --baseline holds a published plan to the artifact that was approved.

There is no undo, no clean, no baseline, no history repair and no forced unlock. Those omissions are deliberate.

Quick start on SQLite

uv sync --all-extras
uv run migr8 --help
cd examples/sqlite
uv run migr8 status   --config migr8.toml --manifest manifest.toml
uv run migr8 migrate  --config migr8.toml --manifest manifest.toml
uv run migr8 validate --config migr8.toml --manifest manifest.toml

Tests

uv run pytest -m "not oracle and not postgres"   # 617 tests, no services needed
testenv/dbctl.sh up                              # disposable Oracle + PostgreSQL
testenv/dbctl.sh test                            # all 779, with the databases
testenv/dbctl.sh down

tests/test_adapter_contract.py is one contract suite run against every configured adapter, so adding an adapter means filling in a dialect and running it rather than writing a new test file.

The same gates run in CI on every push and pull request, the live-database job included.

Diagnosing a failure

migr8 migrate --log-file /var/log/migr8/run.jsonl   # JSONL event log
migr8 migrate --json | jq '{outcome, failed_migration, phase}'

Every run has a correlation id, printed on failure and present on every log line. The log records each phase with timings and ends with the outcome, the failing migration and the phase.

A failure is reported by exception type and engine error code — ORA-00001, SQLSTATE 23505 — with the operation, phase and identity around it, on stderr, in --json, in the event log and under --verbose alike. The driver's own message is not reproduced, because it quotes the values that produced the error. Two exclusions are stated and there are no others: ctx.log() fields are the author's choice and the author's responsibility, and connection, session and privilege errors raised before any migration runs quote the server, because there the server's message is the diagnostic.

Exit codes

Code Meaning
0 Completed and applicable validation passed.
1 Usage, configuration, unsupported capability, connection or binding error.
2 Manifest/history/source validation failed, including recovery admission.
3 Ordinary migration failure: atomic work rolled back, or restartable remains ACTIVE.
4 Operation outcome unknown after communication failure; rerun to reconcile.
5 Migration lock not acquired within policy.
6 Namespace not initialized; read-only commands only.
7 Metadata damaged or incompatible with the supported layout.
8 Detected transaction-contract violation; durable effects may need remediation.

Layout

src/migr8/
  manifest.py fingerprint.py paths.py staging.py   capture and source integrity
  sqltext.py                                       lexical scanning only, no policy
  model.py statevalidate.py                        durable state and pure validation
  engine.py context.py loader.py latch.py          orchestration and the author facade
  diagnostics.py                                   correlation id and event log
  cli.py readonly.py reporting.py                  three commands and their output
  adapters/base.py                                 the contract, the session rules, the operation guard
  adapters/{oracle,postgres,sqlite}.py             dialect and engine-specific behaviour
docs/  examples/  testenv/  deploy/  tests/
migr8                                              thin entry point for a checkout

adapters imports from the core, and engine, context and checks import adapters.base for the Adapter contract. No core module imports a concrete driver: oracle, postgres and sqlite are reached only through adapters.create, and the engine contains no engine-specific SQL.

Licensing

AGPL-3.0-only (LICENSE), with commercial licenses available separately (COMMERCIAL.md). The model and the dependency audit behind it are in LICENSING.md.

Metadata

Release files for migr8 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for migr8 0.1.0
File Size Uploaded
migr8-0.1.0.tar.gz 293.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for migr8 0.1.0
File Interpreter ABI Platform
migr8-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 424.7 kB

Release files / migr8-0.1.0.tar.gz

Download URL migr8-0.1.0.tar.gz
Size 293.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e5ace029144159637f7c97ef714b136601b33889799064d5b7d0a026ee86042c
BLAKE2b-256 checksum
How to use checksums
9e5f518c46b448a2fca15c5d13b61b2744057b8b7527bb3391d050ad761ffafc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release files / migr8-0.1.0-py3-none-any.whl

Download URL migr8-0.1.0-py3-none-any.whl
Size 131.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c8f5945205a52901ae2da860ec81b96a504d654450140e43d21834c45c0b1817
BLAKE2b-256 checksum
How to use checksums
a3188de265f54e11636eb491fa89bc84cff094609301da2f3794fe86c46a59bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page