Migretti is a database migration tool designed for Python applications utilizing PostgreSQL. It provides a strict, SQL-first approach to schema management, ensuring atomicity, consistency, and traceability of database changes.
To install Migretti, use pip:
pip install migrettiDependencies include psycopg[binary], pyyaml, python-ulid, python-dotenv, and sqlparse.
Initialize a new migration project in your repository root:
mg initThis command creates a migrations/ directory and a mg.yaml configuration file.
Configuration is managed via the mg.yaml file. The tool also supports environment variable overrides and interpolation.
Example mg.yaml:
database:
host: localhost
port: 5432
user: postgres
password: ${DB_PASSWORD}
dbname: my_database
lock_id: 894321
envs:
production:
database:
host: db.prod.example.com
dbname: prod_db
lock_id: 999999
hooks:
pre_apply: echo "Backup starting..."
post_apply: echo "Migration complete."Environment Variables:
MG_DATABASE_URL: Overrides connection settings (e.g.,postgresql://user:pass@host/db).MG_ENV: Selects the active environment profile (default:default).MG_LOCK_ID: Overrides the advisory lock ID.
Environment variable interpolation (e.g., ${VAR}) is supported within mg.yaml.
Generate a new migration script:
mg create add_users_tableThis creates a file in migrations/ with a unique ULID prefix. Edit the file to define the schema changes:
-- migration: Add Users Table
-- id: 01H...
-- migrate: up
CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);
-- migrate: down
DROP TABLE users;Apply all pending migrations:
mg applyTo apply only the next pending migration:
mg upRollback the last applied migration:
mg downRollback multiple steps:
mg rollback 3View the status of all migrations:
mg status
mg listVerify that applied migrations on disk match the database checksums:
mg verifyCertain operations, such as CREATE INDEX CONCURRENTLY, cannot run inside a transaction block. Use the -- migrate: no-transaction directive in your SQL file.
-- migrate: no-transaction
-- migrate: up
CREATE INDEX CONCURRENTLY idx_users ON users(name);If a non-transactional migration fails, Migretti records a "failed" status in the database. You must manually resolve the issue and then fix the migration state.
Preview the SQL to be executed without modifying the database:
mg apply --dry-runFor transactional migrations, Migretti performs a "Smart Dry Run," executing the SQL inside a transaction that is immediately rolled back to ensure validity.
Manage data seeding scripts in the seeds/ directory.
Create a seed file:
mg seed create initial_dataRun all seeds:
mg seedDefine shell commands to run before or after operations in mg.yaml:
hooks:
pre_apply: ./scripts/backup_db.sh
post_rollback: ./scripts/notify_team.shSupported hooks: pre_apply, post_apply, pre_rollback, post_rollback.
Combine multiple pending migrations into a single file to maintain a clean history:
mg squash release_v1When running against environments named prod, production, or live, Migretti requires interactive confirmation unless the --yes flag is provided.
Migretti uses PostgreSQL advisory locks to ensure that only one migration process runs simultaneously, preventing race conditions in distributed deployment environments.
For machine-readable output, use the JSON logging flag:
mg apply --json-logThis software is released under the Apache License 2.0.