Choosing an engine
Twenty engines are supported and the commands are the same on all of them. What differs is what happens when a migration fails half-way, and that is the difference worth knowing before you write your first one.
Start with failure behaviour
Where DDL is transactional, a failed migration rolls back and leaves nothing behind. Where it auto-commits, each statement lands as it runs and a failure stops mid-way — recovery is manual or by undo script, which is why small migrations and a rehearsal matter more on those engines.
Transactional DDL · 13
A failed migration rolls back completely.
PostgreSQL · SQL Server · IBM Db2 · SQLite · DuckDB · Redshift · Aurora · AlloyDB · Neon · Supabase · Timescale · Citus · CockroachDB
DDL auto-commits · 4
Completed statements stay applied after a failure.
MySQL · MariaDB · Oracle · YugabyteDB
No transactions · 1
No rollback of any kind. Keep each migration small.
Azure Cosmos DB
The full grid, including drivers, install extras and quirks, is on the capability matrix. Installation is one pip extra; this page is only the differences that change how you write migrations.
Four families
PostgreSQL and the compatible family
PostgreSQL · Aurora · AlloyDB · Neon · Supabase · Timescale · Citus · CockroachDB · YugabyteDB
All speak psycopg and inherit the PostgreSQL provider, so most declare no differences at all. The extra installs the driver; database.type selects the plugin and its quirks.
Traditional servers
MySQL · MariaDB · Oracle · SQL Server · IBM Db2
Each has its own driver and its own identifier, DDL and locking behaviour. Read the engine page before the first release: three of the five auto-commit DDL.
Embedded
SQLite · DuckDB
A file, no server, no credentials, transactional DDL. Ideal for tests and local rehearsal of the tool itself.
Analytics and document
Amazon Redshift · Snowflake · Azure Cosmos DB · MongoDB
Warehouses and document stores. Redshift has no indexes; Snowflake auto-commits DDL; Cosmos and MongoDB have no SQL DDL and take Python migrations.
Limits worth knowing up front
Changing engine later
The CLI, the Python API, the history table and the file naming convention do not change with the engine. What does not travel is the SQL inside your migrations: dialect differences are yours to handle, and validate-sql checks a directory against a named dialect so a mismatch surfaces before a release rather than during one.
For local rehearsal, an embedded engine costs nothing to set up — but do not rehearse a MySQL release on SQLite. Failure behaviour differs, so the rehearsal would prove the wrong thing.