Doctrine migrations turn reviewed PHP migration classes into schema changes on the database used by a Symfony application. Running them is part of a release because the code and database shape must reach the same version before new entities, repositories, or message-backed tables are used.
Symfony Console exposes Doctrine Migrations through php bin/console, and the command reads the same DATABASE_URL and environment as the application. During deployment, APP_ENV=prod should already point the console at the production connection; in local rehearsal, a SQLite URL can keep the run disposable.
Run only migration files that have been reviewed and committed, and take a database backup or rollback snapshot before schema changes that are hard to reverse. A controlled pass checks pending versions, dry-runs SQL at verbose output, applies the migration without an interactive prompt, and verifies both the version table and the affected schema.
If the deployment shell does not already export APP_ENV=prod, select the production environment for each console invocation so Doctrine uses the intended database connection.
public function up(Schema $schema): void { $this->addSql( 'CREATE TABLE product (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(80) NOT NULL)' ); // Review every additional SQL statement before running the migration. }
Pause before running if the migration drops data, rewrites large tables, adds required columns to existing rows, or needs an application rollback plan.
$ php bin/console doctrine:migrations:list +------------------------------------------+--------------+-------------+----------------+-------------+ | Migration Versions | | +------------------------------------------+--------------+-------------+----------------+-------------+ | Migration | Status | Migrated At | Execution Time | Description | +------------------------------------------+--------------+-------------+----------------+-------------+ | DoctrineMigrations\Version20260625075716 | not migrated | | | | +------------------------------------------+--------------+-------------+----------------+-------------+
$ php bin/console doctrine:migrations:migrate --dry-run --no-interaction -vv [notice] Migrating (dry-run) up to DoctrineMigrations\Version20260625075716 [info] ++ migrating DoctrineMigrations\Version20260625075716 [debug] CREATE TABLE product (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(80) NOT NULL) ##### snipped ##### [notice] finished in 3.3ms, used 24M memory, 1 migrations executed, 5 sql queries [OK] Successfully migrated to version: DoctrineMigrations\Version20260625075716
-vv prints the SQL emitted during the dry run. Paste the SQL into the migration risk checker before production when the migration touches large or hot tables.
Tool: Database Migration Risk Checker
$ php bin/console doctrine:migrations:migrate --no-interaction [notice] Migrating up to DoctrineMigrations\Version20260625075716 [notice] finished in 3.3ms, used 24M memory, 1 migrations executed, 3 sql queries [OK] Successfully migrated to version: DoctrineMigrations\Version20260625075716
Do not use --no-interaction as a shortcut for skipping review. It belongs in deployment automation after the target database, backup, and migration SQL have already been checked.
$ php bin/console doctrine:migrations:list +------------------------------------------+----------+---------------------+----------------+-------------+ | Migration Versions | | +------------------------------------------+----------+---------------------+----------------+-------------+ | Migration | Status | Migrated At | Execution Time | Description | +------------------------------------------+----------+---------------------+----------------+-------------+ | DoctrineMigrations\Version20260625075716 | migrated | 2026-06-25 07:57:26 | 0.001s | | +------------------------------------------+----------+---------------------+----------------+-------------+
$ php bin/console dbal:run-sql 'SELECT version FROM doctrine_migration_versions' ------------------------------------------ version ------------------------------------------ DoctrineMigrations\Version20260625075716 ------------------------------------------
$ php bin/console dbal:run-sql "SELECT name, type, [notnull] AS required FROM pragma_table_info('product')" ------ ------------- ---------- name type required ------ ------------- ---------- id INTEGER 1 name VARCHAR(80) 1 ------ ------------- ----------
Use the equivalent inspection query for the production database engine when the migration targets MySQL, MariaDB, PostgreSQL, or another server-backed database.