You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:05:55