Symfony2:使用Doctrine迁移和schema_filter实现多个数据库连接/实体管理器

5
我目前有一个单一的数据库/实体管理器Symfony2(2.1)应用程序,包括Doctrine迁移,正在添加第二个数据库连接和实体管理器,但在让Doctrine迁移执行我想要的操作时遇到了问题。
基本上,我希望我的大多数实体位于我的第一个“默认”数据库中,并且在我的第二个数据库中有几个新的实体/表 - 然后让Doctrine迁移管理模式的任何更改。文档似乎暗示您可以在连接上设置“schema_filter”来实现此目的。
(用例是这样的:我们的应用程序有几个白标代理商的安装程序,每个安装程序都有自己的主数据库。但是,我们正在实施交互式帮助,这将由我们在CMS /博客类型界面中编写并通过这个第二个数据库提供给所有安装程序。)
到目前为止,我的Doctrine配置如下(来自app/config/config.yml):
    dbal:
        default:
            driver:   %database_driver%
            host:     %database_host%
            port:     %database_port%
            dbname:   %database_name%
            user:     %database_user%
            password: %database_password%
            charset:  UTF8
            schema_filter: ~^(?!help_)~
        cross_site:
            driver:   %crossite_database_driver%
            host:     %crossite_database_host%
            port:     %crossite_database_port%
            dbname:   %crossite_database_name%
            user:     %crossite_database_user%
            password: %crossite_database_password%
            charset:  UTF8
            schema_filter: ~^help_~

orm:
    auto_generate_proxy_classes: %kernel.debug%
    default_entity_manager: default
    entity_managers:
        default:
            connection: default
            mappings:
                <most of the bundles>
        help:
            connection: cross_site
            mappings:
                HelpBundle: ~

意图是让大部分实体/表在“默认”数据库中,但排除任何以“help_”开头的表。相反,第二个数据库应该只包含以“help_”开头的表。
然而,无论我使用哪个实体管理器运行Doctrine迁移,它都会简单地包括所有表,而不考虑它们的名称。
php app/console doctrine:migrations:migrate # includes every table including help_*
php app/console doctrine:migrations:migrate --em="help" # includes every table

我是否误用了schema_filter?有没有其他方法来实现我的目标?
更新:情况实际上更糟...在使用“help”实体管理器进行第一次迁移后,我不能再使用--em =“help”运行其他迁移;我收到以下错误:
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'migration_versions' already exists 

迁移仍然在原始 EM 上很好地工作。需要帮忙吗?
1个回答

6
所以,我学到了几件事情,这些帮助我解决了问题......在这里发布,以防其他人遇到类似的困境。
  1. doctrine:migrations:migrate基本上忽略了您的schema_filter。这可能是它应该做的……它的工作只是运行您的迁移文件中的SQL。
  2. doctrine:migrations:diff是您应该关注schema_filter的地方。它将通过您的schema_filter查看数据库的当前状态。记得通过--em=[name]向diff命令和migrate命令传递正确的实体管理器。
  3. 不要使用schema_filter排除migration_versions表。如果这样做,doctrine迁移包会认为它不存在,并始终尝试重新创建它(这将失败)。
所以,我添加了两个东西来更或多少地实现我的目标。在我第二个数据库的配置中,我调整了schema_filter,也包括migration_versions表:
            cross_site: 
                schema_filter: ~^(help_|migration_versions)~

我还向处理第二个数据库/实体管理器的任何迁移版本文件(位于app / DoctrineMigrations中)添加了以下代码:
$this->skipIf( $this->connection->getDatabase() != '[second DB name]', 'Skipping help database.' );

这样可以确保只应该在第二个数据库中的表不会污染原始数据库。请注意,这应该在up()和down()方法中都加入。


1
你能详细解释一下你的“cross_site”配置吗? - hardik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接