On doctrine/doctrine-migrations-bundle
2.* this was relatively simple - use the --em
option (and use ContainerAwareInterface
to skip any migrations from a different em/connection).
Now (on doctrine/doctrine-migrations-bundle
3.2.2), it seems the --em
option is ignored, and the default em/connection is always specified, meaning the migrations for the default em are applied to every database. Edit: As pointed out in comments - --em
is not ignored, it's passed through directly, it's rather our ContainerAwareInterface
approach that's no longer valid.
There is a lot of conflicting information on how to set this up, some suggesting it should "just work" (Symfony Docs) and other describing workarounds (Issue):
https://symfony.com/doc/current/doctrine/multiple_entity_managers.html https://github.com/doctrine/DoctrineMigrationsBundle/issues/38
How does one configure this new version (3) of doctrine/doctrine-migrations-bundle
to apply migrations only to their matching entity/db?
Edit: I've included below our config previous to upgrading, which along with the ContainerAwareInterface
connection filtering approach, allowed filtering migrations to run only against the appropriate entity manager.
Our existing "doctrine/doctrine-bundle": "1.12.8"
config (shortened, but shows multiple entity managers):
doctrine:
dbal:
connections:
default:
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
driver: '%database_driver%'
server_version: mariadb-10.4.11
host: '%database_host%'
port: '%database_port%'
dbname: autotempest
user: '%database_user%'
password: '%database_password%'
mapping_types:
enum: string
model:
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
driver: '%database_driver%'
server_version: mariadb-10.4.11
host: '%database_host%'
port: '%database_port%'
dbname: autotempest_models
user: '%database_user%'
password: '%database_password%'
mapping_types:
enum: string
wrapper_class: App\Doctrine\ConnectionWrapper\ConnectionModel
persistent: true
orm:
auto_generate_proxy_classes: '%kernel.debug%'
entity_managers:
default:
connection: default
mappings:
App:
type: 'annotation'
dir: '%kernel.project_dir%/src/Entity/Main'
prefix: 'App\Entity\Main'
model:
connection: model
mappings:
TempestModelBundle:
type: 'annotation'
dir: 'Entity'
prefix: 'Tempest\Bundle\ModelBundle\Entity'
Our "doctrine/doctrine-migrations-bundle": "2.1.2"
config:
doctrine_migrations:
dir_name: '%kernel.project_dir%/src/Migrations'
namespace: Application\Migrations
Also mentioned in my question, there is an open issue on the
DoctrineMigrationsBundle
from 2012 describing the problem of dealing with migrations when using multiple entity managers: https://github.com/doctrine/DoctrineMigrationsBundle/issues/38. It seems there are several options for workarounds to this issue as described there, we just needed to dig and try each of them to find the best one for our situation.Container Aware Migrations
On Symfony 3, we were using the
ContainerAwareInterface
approach. Described in the above issue:This is no longer really a valid solution when moving to Symfony 4 however, due to
ContainerAware
classes being deprecated in favor of dependency injection.Pass configuration directly
Another approach mentioned in the github issue above. The idea here is to have a separate configuration file for each entity manager like the following:
This is passed directly to the command, along with the entity manager like this:
bin/console doctrine:migrations:migrate --em default --configuration config/packages/migrations/base.yaml
. These separate config files replace the singleconfig/packages/doctrine_migrations.yaml
configuration file.This was also not viable for us, as we still needed to inject services into our migrations using the
services
configuration option ofDoctrineMigrationsBundle
, and--configuration
only passes configuration options directly through todoctrine/migrations
, which doesn't support theservices
configuration option.Initially on
DoctrineMigrationsBundle
3.0, this approach was complicated by the fact that the--em
and--conn
options were dropped completely, so it was also necessary to create a wrapper on top of theDoctrineMigrationsBundle
commands to re-implement these options (described in more detail here). This is no longer necessary onDoctrineMigrationsBundle
3.1+ (which restored these options).Use
DoctrineMigrationsMultipleDatabaseBundle
Also mentioned in the github issue thread, this bundle implements what we needed exactly (and ended up using) - per-entity configuration for
DoctrineMigrationsBundle
, so we can also include ourservices
config for migration dependency injection. Initially I misconfigured this - it's important that the basedoctrine_migrations.yaml
config only includes config for the default entity manager. Sample working config provided by the package author (version 0.3.3):