doctrine / migrations

Doctrine Database Migrations Library
https://www.doctrine-project.org/projects/migrations.html
MIT License
4.68k stars 388 forks source link

Alternative connection via --conn option is ignored #1160

Open alexgit2k opened 3 years ago

alexgit2k commented 3 years ago

Bug Report

Summary

In #1023 the option to allow alternative connections via --conn option was added. However as also stated in https://github.com/doctrine/migrations/issues/1062#issuecomment-801171576 and https://github.com/doctrine/migrations/issues/1062#issuecomment-807348508 an alternative connection specified via --conn option is ignored and the default connection is used instead.

Current behavior

Default connection is used.

How to reproduce

bin/console doctrine:migrations:migrate --dry-run -vvv --no-interaction --conn=migrations
doctrine:
    dbal:
        default_connection: default
        # configure these for your database server
        connections:
            default:
                url: '...'
            migrations:
                url: '...'

Expected behavior

Alternative connection should be used.

goetas commented 3 years ago

can you please tell us which version of the doctrine migrations bundle are you using?

alexgit2k commented 3 years ago

@goetas: of course the latest release:

$ ./vendor/bin/doctrine-migrations -v
Doctrine Migrations 3.1.2@1c2780df6b58998f411e64973cfa464ba0a06e00
dant89 commented 3 years ago

Experiencing the same issue with:

php bin/doctrine-migrations -v
Doctrine Migrations 3.1.0@260991be753a38aa25b6f2d13dbb7f113f8dbf8f
goetas commented 3 years ago

can you please tell us which version of the doctrine migrations bundle are you using?

Are you using the symfony bundle? if yes, what is the bundle version (not the migrations lib)

ureimers commented 3 years ago

Hi, as I have the same problem (stated in https://github.com/doctrine/migrations/issues/1062#issuecomment-801171576), I switched to the DEV branch of the migrations bundle, just to be sure not to miss any unreleased fix to this:

doctrine/doctrine-migrations-bundle      3.2.x-dev fda5e69
doctrine/migrations                      3.2.0

It doesn't matter what is defined as the --conn parameter, it seems to be simply ignored:

bin/console doctrine:migrations:migrate -n --conn=this-connection-does-not-exist

 [OK] Already at the latest version ("DoctrineMigrations\Version20210727091159")
goetas commented 3 years ago

@ureimers hmm. that is weird and looks like a big :(

goetas commented 3 years ago

So, after looking into the issue, there is a problem when there is only the default entity manager... the --conn option is ignore and always the entity manager connection is choosen.

could you share your doctrine migrations and doctrine connection configs?

ureimers commented 3 years ago

Hi @goetas, I was away for a month, so please excuse the late response. Here are my configurations (I removed some internal bundle names):

# doctrine.yaml

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                url: '%env(resolve:DATABASE_URL)%'
                charset: UTF8
            live:
                url: '%env(resolve:LIVE_DATABASE_URL)%'
                charset: UTF8
            user:
                url: '%env(resolve:USER_DATABASE_URL)%'
                charset: UTF8
            live_user:
                url: '%env(resolve:LIVE_USER_DATABASE_URL)%'
                charset: UTF8
            log:
                url: '%env(resolve:DATABASE_URL)%'
                charset: UTF8

    orm:
        auto_generate_proxy_classes: true
        default_entity_manager: default
        entity_managers:
            default: &doctrine_default_entity_manager
                connection: default
                naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
                mappings:
                    # [...] lots of custom bundles
                    FOSUserBundle: ~
                    SonataUserBundle: ~
                dql:
                    numeric_functions:
                    # [...] some DQL functions
            live:
                <<: *doctrine_default_entity_manager
                connection: live

            user:
                <<: *doctrine_default_entity_manager
                connection: user
# doctrine_migrations.yaml

doctrine_migrations:
    services:
        'Doctrine\Migrations\Version\MigrationFactory': 'App\Migrations\MigrationFactoryDecorator'
    migrations_paths:
        # namespace is arbitrary but should be different from App\Migrations
        # as migrations classes should NOT be autoloaded
        'DoctrineMigrations': '%kernel.project_dir%/migrations'
goetas commented 3 years ago

hmm, that seems weird. is there a way to reproduce this somehow in a failing test case?

feosys commented 3 years ago

has it already been fixed?

goetas commented 3 years ago

has it already been fixed?

you did not mange to reproduce it? or you saw a commit fixing it?

mussbach commented 2 years ago

I face the same issue and you seem to be right:

So, after looking into the issue, there is a problem when there is only the default entity manager... the --conn option is ignore and always the entity manager connection is choosen.

This is the case for us as well. As I am not very familiar with the code: Where do you suggest to locate the Test?

goetas commented 2 years ago

@mussbach so you have one entity manager and multiple connections, right?

and commands and diff will need to the entity manager, while the commands as migrate will need to choose on which connection to run.

So my question is: why do you have two connections if you have only one entity manager? what is doing the other connection?

mussbach commented 2 years ago

Yes, you understood it correctly. Our usecase is that we have a privileged user with alter (and some more) rights that we want to use only during migration to keep the permission set for the „ordinary“ user as small as possible. Both users need the same entities to be managed.

Kleinast commented 2 years ago

I tried to update from 2.x to 3.4 and have the same error with multiple connection. Is there a workaround or a commit who fix it ?

Thx in advance

schodemeiss commented 2 years ago

I have the same issue. I have 2 connections, lets say "default" and "database_2" but only one Entity Manager on "default" (my second connection doesn't need Entities.

If I provide "--conn database_2" to any of the migration commands, it always falls back to the "default".

Any ideas how to sort this?

ToGoLimango commented 2 years ago

i could solve this for me by adding "connection: migrations to doctrine_migrations.yaml (or the connection you need than)

so at the end its looking like this:

doctrine_migrations:
    connection: migrations
    migrations_paths:
        'DoctrineMigrations': '%kernel.project_dir%/migrations'
kSHerstyanikov commented 2 years ago

has it already been fixed?

revilon1991 commented 2 years ago

While we are waiting for the fix we can use flag --em instadeof --conn. Just don't forget to configure an enity manager and set nessasary connection.

# config/packages/doctrine.yaml
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                url: '%env(resolve:DATABASE_URL)%'
                # ...
            migrations: # <--- connection for migration
                url: '%env(resolve:DATABASE_MIGRATIONS_URL)%'
                # ...
    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                # ...
            migrations: # <--- orm manager for connection
                connection: migrations
                # ...

and run

php bin/console doctrine:migrations:migrate --no-interaction --em=migrations
cavasinf commented 1 year ago

Same case here.. Using @revilon1991 solution seems to work, but we should test every possible case before.

Because with the mapping, we have Bundle that add a CompilerPass, and this doesn't work with other EntityManager.

        $mappings = [
            realpath(__DIR__ . '/Resources/config/doctrine') => 'Allsoftware\SymfonyBundle\Entity',
        ];

        $container->addCompilerPass(
            DoctrineOrmMappingsPass::createXmlMappingDriver(
                $mappings,
                ['allsoftware.symfony.model_manager_name'],
                'allsoftware.symfony.backend_type_orm'
            )
        );

Result of php bin/console debug:config doctrine:

doctrine:
    orm:
        entity_managers:
            default:
                [...]
                mappings:
                    App:
                        is_bundle: false
                        type: attribute
                        dir: /var/www/html/src/Entity
                        prefix: App\Entity
                        alias: App
                        mapping: true
+                   AllsoftwareSymfonyBundle:
+                       type: attribute
+                       dir: src/Model
+                       prefix: Allsoftware\SymfonyBundle\Model
+                       mapping: true
            client1:
                [...]
                mappings:
                    App:
                        is_bundle: false
                        type: attribute
                        dir: /var/www/html/src/Entity
                        prefix: App\Entity
                        alias: App
                        mapping: true
HaiD84 commented 1 year ago

The problem seems to be with Doctrine\Bundle\MigrationsBundle\DependencyInjection\CompilerPass\ConfigureDependencyFactoryPass. If preferred connection/em not defined and there is any entity manager then DependencyFactory::fromEntityManager is used, effectively ignoring --conn option. Like already mentioned possible workaround would be to add connection parameter to doctrine_migrations.yaml. That way DependencyFactory::fromConnection will be used, allowing --conn option, but now ignoring --em.