Symfony 7.2中Doctrine Migrations多数据库迁移异常问题求助
Symfony 7.2 + Doctrine Migrations 多数据库迁移问题解决
问题
配置module1和module2两个EntityManager及对应迁移路径后,执行php bin/console doctrine:migrations:migrate --env=dev --no-interaction --em=module1时,两个模块的迁移脚本会被同时执行到module1数据库中。
配置详情
Doctrine Migrations 调试配置
Current configuration for extension with alias "doctrine_migrations" ==================================================================== doctrine_migrations: migrations_paths: App\Module\Module1\Resource\Migration: /var/www/html/src/Module/Module1/Resource/Migration App\Module\Module2\Resource\Migration: /var/www/html/src/Module/Module2/Resource/Migration em: module1 enable_profiler: false services: { } factories: { } storage: table_storage: table_name: null version_column_name: null version_column_length: null executed_at_column_name: null execution_time_column_name: null migrations: { } connection: null all_or_nothing: false check_database_platform: true custom_template: null organize_migrations: false transactional: true
doctrine.yaml 配置
doctrine: dbal: connections: module1: url: '%env(resolve:DATABASE_MODULE1_URL)%' driver: 'pdo_mysql' server_version: '8.0' charset: utf8mb4 mapping_types: enum: string module2: url: '%env(resolve:DATABASE_MODULE2_URL)%' driver: 'pdo_mysql' server_version: '8.0' charset: utf8mb4 mapping_types: enum: string orm: auto_generate_proxy_classes: true default_entity_manager: module1 entity_managers: module1: connection: module1 naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware mappings: Module1: is_bundle: false dir: '%kernel.project_dir%/src/Module/Module1/Entity' prefix: 'App\Module\Module1\Entity' alias: Module1 module2: connection: module2 naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware mappings: Module2: is_bundle: false dir: '%kernel.project_dir%/src/Module/Module2/Entity' prefix: 'App\Module\Module2\Entity' alias: Module2
根目录 doctrine_migrations.yaml 配置
imports: - { resource: '../../src/Module/Module1/Resource/Config/Package/doctrine_migrations.yaml' } - { resource: '../../src/Module/Module2/Resource/Config/Package/doctrine_migrations.yaml' } doctrine_migrations: enable_profiler: false
Module1 独立迁移配置
doctrine_migrations: migrations_paths: 'App\Module\Module1\Resource\Migration': '%kernel.project_dir%/src/Module/Module1/Resource/Migration' em: module1
问题原因
当前配置通过import合并了两个模块的迁移设置,导致migrations_paths包含了两个模块的路径。即使指定--em=module1,Doctrine Migrations仍会加载所有已配置的迁移脚本,并将它们全部应用到指定EntityManager对应的数据库中。
解决方案
使用Doctrine Migrations的Profiles功能为每个EntityManager隔离迁移配置,确保每个模块的迁移仅对应自身的数据库。
方案1:统一在根配置中定义Profiles
修改根目录doctrine_migrations.yaml:
doctrine_migrations: enable_profiler: false profiles: # Module1 专属迁移配置 module1: migrations_paths: 'App\Module\Module1\Resource\Migration': '%kernel.project_dir%/src/Module/Module1/Resource/Migration' em: module1 # Module2 专属迁移配置 module2: migrations_paths: 'App\Module\Module2\Resource\Migration': '%kernel.project_dir%/src/Module/Module2/Resource/Migration' em: module2
删除模块内的独立迁移配置文件,执行迁移时通过--profile指定目标模块:
# 执行Module1的迁移 php bin/console doctrine:migrations:migrate --env=dev --no-interaction --profile=module1 # 执行Module2的迁移 php bin/console doctrine:migrations:migrate --env=dev --no-interaction --profile=module2
方案2:保留模块独立配置并关联到Profiles
如果需要保留模块内的配置文件,修改根目录doctrine_migrations.yaml:
doctrine_migrations: enable_profiler: false profiles: module1: imports: - { resource: '../../src/Module/Module1/Resource/Config/Package/doctrine_migrations.yaml' } module2: imports: - { resource: '../../src/Module/Module2/Resource/Config/Package/doctrine_migrations.yaml' }
模块内的配置文件无需修改,执行迁移时同样使用--profile参数指定模块即可。
说明
Profiles功能会为每个EntityManager创建独立的迁移上下文,每个上下文仅加载自身配置的迁移路径,彻底避免跨模块迁移的问题。
内容的提问来源于stack exchange,提问作者nnikolay
相关产品推荐
相关产品推荐

