Symfony Doctrine Migrations upgrade to version 3
Before we begin, you should take a look at one of my previous articles “How to solve Symfony 5 and Doctrine Migrations Bundle 3 upgrade error: Unrecognized options “dir_name, namespace” under “doctrine_migrations”.” That article covers the base case when you don’t have any migrations and, technically, everything worked fine — until actual migrations needed to be migrated to the new Doctrine Bundle version.
This article covers what needs to be done in order to update existing migrations.
Update for existing migrations
If you have followed the first article, you will encounter further post-update issues if you have migrations that were already executed before the Doctrine bundle upgrade. To resolve the issues, follow these steps:
Make sure to have the correct environment loaded
This was covered in the original article, but let’s make sure it’s done before proceeding. If you had any other environment set in the
.env file, the upgrade could rewrite it and set the environment back to
dev. Make sure to revert it back to the proper environment (In my case, it was
Move the existing migration files
Move (cut and paste) your existing migrations (their
.php files) to the new Doctrine migrations folder.
Previous Doctrine migrations folder was
src/Migrations while the new one is
migrations (relative to your project root directory). To make sure you’re using the correct folder, open
config/packages/doctrine_migrations.yaml file and look for
migration_paths configuration option. It should contain the following (new) namespace definition and its directory
Sync Doctrine metadata storage
php bin/console doctrine:migrations:sync-metadata-storage.
Doctrine changed its migrations version database table in version 3.0. The default table name in 2.x was
migration_versions and the new table name is
doctrine_migration_versions. The table structure is different in 3.0 as well — a new column
execution_time is introduced which contains an amount of milliseconds the migration took when it was executed. The
sync-metadata-storage command should create the new
doctrine_migration_versions database table for you.
Import data from the old migration versions table
The previous command set up the new default Doctrine migrations database table. The only thing left to do now is to let Doctrine know that you’ve already executed some migrations in the previous version.
To do that, run the following MySQL query:
INSERT INTO doctrine_migration_versions (version, executed_at, execution_time) SELECT concat("DoctrineMigrations\\Version", version), executed_at, 1 FROM migration_versions;
This query does a couple of things:
versioncolumn in the old table contained only migration timestamp (ex.
20200820072236). The new Doctrine bundle supports multiple namespaces, the default one being
DoctrineMigrations. So, in order to transfer the old migrations to the new table, we’re adding
DoctrineMigrations\Versionas a prefix in order to get the new format:
We are adding a sample value
1as the value of new
execution_timecolumn. You can put anything here, since it only marks the amount of milliseconds a migration took when executed.
Cleanup the old table
If everything up until now went smoothly, the old
migration_versions table is now obsolete. But, before deleting it, verify that the migrations are upgraded successfully with
php bin/console doctrine:migrations:status. If
Executed Unavailable value is
0 we should be fine.
Just as a precaution, export the structure and data of the old
migration_versions table. After a breaking, backwards incompatible change like this, you never know if anything else is going to break in the future.
You can now delete
migration_versions table from the database.
We have done the following:
Moved the old migration
phpfiles to the new migrations directory;
Synced Doctrine migrations metadata storage;
Let Doctrine create the new default
Convert to the new format and import the old migrations to the new database table;
Verify that the upgrade went smoothly;
Backup (export) the old
migration_versionsdatabase table and then delete it.
That’s it for now. This should conclude the Doctrine migrations bundle upgrade to version 3.0.