Basic run scenarios
Normal cycle
The typical migration workflow: first initialize the project with migrate:init, then apply all pending migrations with migrate:up. Roll back changes when needed with migrate:down. Note: migrate:down without --limit rolls back all applied migrations to the state before any migrations — to roll back only one, use --limit=1.
/example $ php cli.php migrate:init
[sqlite/db] initialization: setup.sql done
/example $ php cli.php migrate:up
[sqlite/db] up: 202501011024_entity_create.sql done
[sqlite/db] up: 202501021024_account_create.sql done
[sqlite/db] up: 202501021025_account_email.sql done
/example $ php cli.php migrate:down
[sqlite/db] down: 202501021025_account_email.sql done
[sqlite/db] down: 202501021024_account_create.sql done
[sqlite/db] down: 202501011024_entity_create.sql doneAtomic run: --exactly-all
The --exactly-all flag combines all migrations in a run into a single batch. If any migration fails, the entire batch is rolled back and the database remains in its original state. Use this option where an all-or-nothing approach is important — for example, when deploying to production.
/example $ php cli.php migrate:up --exactly-all
[sqlite/db] up: 202501011024_entity_create.sql done
[sqlite/db] up: 202501021024_account_create.sql done
[sqlite/db] up: 202501021025_account_email.sql doneRepeatable migrations: --with-repeatable
The --with-repeatable flag instructs the command to apply repeatable migrations after regular ones. They are taken from the <source>-repeatable directory and re-applied every time the file content changes — convenient for views, functions, and other idempotent schema objects. Note: --with-repeatable is incompatible with --dry-run.
/example $ php cli.php migrate:up --with-repeatable
[sqlite/db] up: 202501011024_entity_create.sql done
[sqlite/db] up: 202501021024_account_create.sql done
[sqlite/db] up: 202501021025_account_email.sql done
[sqlite/db] repeatable: 202501011024_entity_correction.sql done
[sqlite/db] repeatable: 202501011024_entity_correction_2.sql doneDatabase filter: --db
A single Migrator can have multiple Migration objects registered. The --db flag selects a specific database for the command. The database name is formed as <driver-name>/<source-name> — for example, pgsql/main or sqlite/db. Without --db, the command is applied to all registered databases simultaneously.
/example $ php cli.php migrate:up --db=pgsql/main
[pgsql/main] up: 202501011024_entity_create.sql doneDry run: --dry-run
The --dry-run flag puts the command into test-run mode: the utility prints the migration plan but does not apply any changes to the database. This is convenient for CI checks and for reviewing migrations before real application.
/example $ php cli.php migrate:up --dry-run
[sqlite/db] up: 202501011024_entity_create.sql (dry-run) done