Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrations run out of chronological order if you have multiple namespaces defined #509

Open
samuel-sol opened this issue Oct 16, 2023 · 1 comment

Comments

@samuel-sol
Copy link

Let's say you have the follow doctrine_migrations.yaml file:

doctrine_migrations:
    migrations_paths:
        'DoctrineMigrations': '%kernel.project_dir%/migrations'
        'MyBundleDoctrineMigrations': '@MyBundle/migrations'
        'MyOtherBundleDoctrineMigrations': '@MyOtherBundle/migrations'
    enable_profiler: '%kernel.debug%'

When you run the doctrine:migrations:migrate command, doctrine will check all the directories, compare with the current table and get what it has to execute. The issue is that it sorts the migrations to be executed by its full path, and not just the VersionYYYYMMDDHIS part of the class name. That means it might run migrations out of chronological order .

For example, if the command finds the following migrations to execute:

DoctrineMigrations\Version20230101000000
DoctrineMigrations\Version20230201000000
DoctrineMigrations\Version20230301000000 
DoctrineMigrations\Version20230401000000
OtherBundleDoctrineMigrations\Version20230410000000
OtherBundleDoctrineMigrations\Version20230510000000
BundleDoctrineMigrations\Version20230120000000
BundleDoctrineMigrations\Version20230220000000
BundleDoctrineMigrations\Version20230520000000

They will be executed in the following order:

BundleDoctrineMigrations\Version20230120000000
BundleDoctrineMigrations\Version20230220000000
BundleDoctrineMigrations\Version20230520000000
DoctrineMigrations\Version20230101000000
DoctrineMigrations\Version20230201000000
DoctrineMigrations\Version20230301000000 
DoctrineMigrations\Version20230401000000
OtherBundleDoctrineMigrations\Version20230410000000
OtherBundleDoctrineMigrations\Version20230510000000

When chronological it should be

DoctrineMigrations\Version20230101000000
BundleDoctrineMigrations\Version20230120000000
DoctrineMigrations\Version20230201000000
BundleDoctrineMigrations\Version20230220000000
DoctrineMigrations\Version20230301000000 
DoctrineMigrations\Version20230401000000
OtherBundleDoctrineMigrations\Version20230410000000
BundleDoctrineMigrations\Version20230520000000
OtherBundleDoctrineMigrations\Version20230510000000

This is a problem if one of your bundles depends on tables maintained by another bundle. Even if you define on your composer.json the correct version minimum req, if both packages are added on the same deploy, the migrations will break because they will not run on chronological order.

@systemasis
Copy link

I'm running into this problem as well.

I created my comparator to strip the versions from their namespaces before comparing them :

<?php

declare(strict_types=1);

namespace App\Migrations\Version\Comparator;

use Doctrine\Migrations\Version\Comparator;
use Doctrine\Migrations\Version\Version;

/**
 * Compares two Versions after stripping them from their respective namespaces
 */
class NamespaceUnwiseAlphabeticalComparator implements Comparator
{
    public function compare(Version $a, Version $b): int
    {
        $explodedA = explode('\\', (string) $a);
        $explodedB = explode('\\', (string) $b);

        return \strcmp(end($explodedA), end($explodedB));
    }
}
# config/packages/doctrine_migrations.yaml
doctrine_migrations:
    services:
        'Doctrine\Migrations\Version\Comparator': 'App\Migrations\Version\Comparator\NamespaceUnwiseAlphabeticalComparator'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants