如何在 DoctrineMigrationsBundle 3 中处理多个实体管理器的迁移
How to handle migrations with multiple entity managers in DoctrineMigrationsBundle 3
在 doctrine/doctrine-migrations-bundle
2.* 这相对简单 - 使用 --em
选项(并使用 ContainerAwareInterface
跳过来自不同 em/connection 的任何迁移)。
现在(在 doctrine/doctrine-migrations-bundle
3.2.2 上),似乎忽略了 --em
选项,并且始终指定默认的 em/connection,这意味着默认 em 的迁移是适用于每个数据库。编辑:正如评论中指出的那样 - --em
没有被忽略,它直接通过,而是我们的 ContainerAwareInterface
方法不再有效。
关于如何设置它有很多相互矛盾的信息,一些建议它应该“正常工作”(Symfony 文档)和其他描述解决方法(问题):
https://symfony.com/doc/current/doctrine/multiple_entity_managers.html
https://github.com/doctrine/DoctrineMigrationsBundle/issues/38
如何配置 doctrine/doctrine-migrations-bundle
的这个新版本 (3) 以仅将迁移应用于匹配的 entity/db?
编辑:我在升级前的配置下面包含了它,连同 ContainerAwareInterface
连接过滤方法,允许过滤迁移到 运行 仅针对适当的实体管理器。
我们现有的 "doctrine/doctrine-bundle": "1.12.8"
配置(缩短,但显示多个实体管理器):
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'
我们的 "doctrine/doctrine-migrations-bundle": "2.1.2"
配置:
doctrine_migrations:
dir_name: '%kernel.project_dir%/src/Migrations'
namespace: Application\Migrations
我的问题中还提到,2012 年 DoctrineMigrationsBundle
上有一个未解决的问题,描述了使用多个实体管理器时处理迁移的问题:https://github.com/doctrine/DoctrineMigrationsBundle/issues/38。如此处所述,似乎有多种解决此问题的方法,我们只需要挖掘并尝试每一种方法,以找到最适合我们情况的方法。
容器感知迁移
在 Symfony 3 上,我们使用的是 ContainerAwareInterface
方法。上期描述:
Currently this can be achieved by using Container Aware Migrations. If one can have the service container injected, he can obtain an instance of some entity manager and its connection.
然而,当迁移到 Symfony 4 时,这不再是一个真正有效的解决方案,因为 ContainerAware
类 被弃用以支持依赖注入。
直接传配置
上述 github 问题中提到的另一种方法。这里的想法是为每个实体管理器创建一个单独的配置文件,如下所示:
# config/packages/migrations/base.yaml
em: default
transactional: false
migrations_paths:
Hyra\Migrations\Base: src/Migrations/Base
table_storage:
table_name: migration_versions
这与实体管理器一起直接传递给命令,如下所示:bin/console doctrine:migrations:migrate --em default --configuration config/packages/migrations/base.yaml
。这些单独的配置文件替换了单个 config/packages/doctrine_migrations.yaml
配置文件。
这对我们来说也不可行,因为我们仍然需要使用 DoctrineMigrationsBundle
的 services
配置选项将服务注入我们的迁移,而 --configuration
仅直接传递配置选项一直到 doctrine/migrations
,它不支持 services
配置选项。
最初在 DoctrineMigrationsBundle
3.0 上,由于 --em
和 --conn
选项被完全删除,这种方法变得复杂,因此还需要在顶部创建一个包装器DoctrineMigrationsBundle
命令中的 re-implement 这些选项 (described in more detail here)。这在 DoctrineMigrationsBundle
3.1+(恢复了这些选项)上不再需要。
使用DoctrineMigrationsMultipleDatabaseBundle
在 github 问题线程中也提到,this bundle 实现了我们所需要的(并最终使用)- DoctrineMigrationsBundle
的 per-entity 配置,因此我们可以还包括我们用于迁移依赖注入的 services
配置。最初我配置错误 - 重要的是基本 doctrine_migrations.yaml
配置只包含默认实体管理器的配置。包作者(版本 0.3.3)提供的示例工作配置:
# doctrine.yaml
doctrine:
dbal:
default_connection: default
connections:
default:
url: '%env(resolve:DATABASE_URL)%'
server_version: mariadb-10.1.26
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
mapping_types:
enum: string
geonames:
url: '%env(resolve:GEONAMES_DATABASE_URL)%'
server_version: mariadb-10.1.26
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
mapping_types:
enum: string
# IMPORTANT: You MUST configure your server version,
# either here or in the DATABASE_URL env var (see .env file)
#server_version: '5.7'
orm:
auto_generate_proxy_classes: true
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/App/Entity/Main'
prefix: 'App\Entity\Main'
alias: Main
geonames:
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
connection: geonames
mappings:
Geonames:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/App/Entity/Geonames'
prefix: 'App\Entity\Geonames'
alias: Geonames
# doctrine_migrations.yaml
doctrine_migrations:
em: default
migrations_paths:
DoctrineMigrations: '%kernel.project_dir%/migrations/Main'
# doctrine_migrations_multiple_database.yaml
doctrine_migrations_multiple_database:
entity_managers:
default:
migrations_paths:
DoctrineMigrations\Main: '%kernel.project_dir%/migrations/Main'
geonames:
migrations_paths:
DoctrineMigrations\Geonames: '%kernel.project_dir%/migrations/Geonames'
在 doctrine/doctrine-migrations-bundle
2.* 这相对简单 - 使用 --em
选项(并使用 ContainerAwareInterface
跳过来自不同 em/connection 的任何迁移)。
现在(在 doctrine/doctrine-migrations-bundle
3.2.2 上),似乎忽略了 --em
选项,并且始终指定默认的 em/connection,这意味着默认 em 的迁移是适用于每个数据库。编辑:正如评论中指出的那样 - --em
没有被忽略,它直接通过,而是我们的 ContainerAwareInterface
方法不再有效。
关于如何设置它有很多相互矛盾的信息,一些建议它应该“正常工作”(Symfony 文档)和其他描述解决方法(问题):
https://symfony.com/doc/current/doctrine/multiple_entity_managers.html https://github.com/doctrine/DoctrineMigrationsBundle/issues/38
如何配置 doctrine/doctrine-migrations-bundle
的这个新版本 (3) 以仅将迁移应用于匹配的 entity/db?
编辑:我在升级前的配置下面包含了它,连同 ContainerAwareInterface
连接过滤方法,允许过滤迁移到 运行 仅针对适当的实体管理器。
我们现有的 "doctrine/doctrine-bundle": "1.12.8"
配置(缩短,但显示多个实体管理器):
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'
我们的 "doctrine/doctrine-migrations-bundle": "2.1.2"
配置:
doctrine_migrations:
dir_name: '%kernel.project_dir%/src/Migrations'
namespace: Application\Migrations
我的问题中还提到,2012 年 DoctrineMigrationsBundle
上有一个未解决的问题,描述了使用多个实体管理器时处理迁移的问题:https://github.com/doctrine/DoctrineMigrationsBundle/issues/38。如此处所述,似乎有多种解决此问题的方法,我们只需要挖掘并尝试每一种方法,以找到最适合我们情况的方法。
容器感知迁移
在 Symfony 3 上,我们使用的是 ContainerAwareInterface
方法。上期描述:
Currently this can be achieved by using Container Aware Migrations. If one can have the service container injected, he can obtain an instance of some entity manager and its connection.
然而,当迁移到 Symfony 4 时,这不再是一个真正有效的解决方案,因为 ContainerAware
类 被弃用以支持依赖注入。
直接传配置
上述 github 问题中提到的另一种方法。这里的想法是为每个实体管理器创建一个单独的配置文件,如下所示:
# config/packages/migrations/base.yaml
em: default
transactional: false
migrations_paths:
Hyra\Migrations\Base: src/Migrations/Base
table_storage:
table_name: migration_versions
这与实体管理器一起直接传递给命令,如下所示:bin/console doctrine:migrations:migrate --em default --configuration config/packages/migrations/base.yaml
。这些单独的配置文件替换了单个 config/packages/doctrine_migrations.yaml
配置文件。
这对我们来说也不可行,因为我们仍然需要使用 DoctrineMigrationsBundle
的 services
配置选项将服务注入我们的迁移,而 --configuration
仅直接传递配置选项一直到 doctrine/migrations
,它不支持 services
配置选项。
最初在 DoctrineMigrationsBundle
3.0 上,由于 --em
和 --conn
选项被完全删除,这种方法变得复杂,因此还需要在顶部创建一个包装器DoctrineMigrationsBundle
命令中的 re-implement 这些选项 (described in more detail here)。这在 DoctrineMigrationsBundle
3.1+(恢复了这些选项)上不再需要。
使用DoctrineMigrationsMultipleDatabaseBundle
在 github 问题线程中也提到,this bundle 实现了我们所需要的(并最终使用)- DoctrineMigrationsBundle
的 per-entity 配置,因此我们可以还包括我们用于迁移依赖注入的 services
配置。最初我配置错误 - 重要的是基本 doctrine_migrations.yaml
配置只包含默认实体管理器的配置。包作者(版本 0.3.3)提供的示例工作配置:
# doctrine.yaml
doctrine:
dbal:
default_connection: default
connections:
default:
url: '%env(resolve:DATABASE_URL)%'
server_version: mariadb-10.1.26
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
mapping_types:
enum: string
geonames:
url: '%env(resolve:GEONAMES_DATABASE_URL)%'
server_version: mariadb-10.1.26
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
mapping_types:
enum: string
# IMPORTANT: You MUST configure your server version,
# either here or in the DATABASE_URL env var (see .env file)
#server_version: '5.7'
orm:
auto_generate_proxy_classes: true
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/App/Entity/Main'
prefix: 'App\Entity\Main'
alias: Main
geonames:
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
connection: geonames
mappings:
Geonames:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/App/Entity/Geonames'
prefix: 'App\Entity\Geonames'
alias: Geonames
# doctrine_migrations.yaml
doctrine_migrations:
em: default
migrations_paths:
DoctrineMigrations: '%kernel.project_dir%/migrations/Main'
# doctrine_migrations_multiple_database.yaml
doctrine_migrations_multiple_database:
entity_managers:
default:
migrations_paths:
DoctrineMigrations\Main: '%kernel.project_dir%/migrations/Main'
geonames:
migrations_paths:
DoctrineMigrations\Geonames: '%kernel.project_dir%/migrations/Geonames'