Symfony Doctrine Migrations upgrade to version 3
Tags: php, symfony, doctrine
Published: 2020-08-20 16:35:02

## Introduction
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”.”](https://dev.to/nikolastojilj12/symfony-and-doctrine-unrecognized-options-dirname-namespace-under-doctrinemigrations-2hbe) 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 `local`).

### 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 `'DoctrineMigrations': '%kernel.project_dir%/migrations'`.

### Sync Doctrine metadata storage

**Run `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:

- `version` column 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\Version` as a prefix in order to get the new format: `DoctrineMigrations\Version2020082007226`

- We are adding a sample value `1` as the value of new `execution_time` column. 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.

## Conclusion

We have done the following:

- Moved the old migration `php` files to the new migrations directory;

- Synced Doctrine migrations metadata storage;

- Let Doctrine create the new default `doctrine_migration_versions`;

- 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_versions` database table and then delete it.

That’s it for now. This should conclude the Doctrine migrations bundle upgrade to version 3.0.

If you liked the article,...
[![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kugdh9szk858ncio2mzi.png)](https://www.buymeacoffee.com/puEW3HvWvP)