根据多个连接使用学说创建多个数据库

时间:2018-09-19 06:53:06

标签: postgresql symfony doctrine-orm entitymanager

出于功能测试目的,基于多个连接创建多个数据库时,我遇到了一个问题。

由于某些限制,我是在 Symfony 3.3应用程序上创建的,因此将计划对Symfony的维护版本进行更新。 要记住的是,我必须处理现有的PostgreSQL数据库,尤其是3个数据库:

  • 数据库A
  • 数据库B
  • 数据库C

我不喜欢从现有数据库设计应用程序。通常,当我从头开始创建应用程序时,我会先设计应用程序和所有业务规则,但这里我别无选择。听起来不错,但是我的应用程序的这一部分是根据现有数据库设计的。无论如何,任何建议都是最欢迎的。 因此,在 App \ Entity 文件夹中,我为3个连接配置了映射:

    与数据库A相关的
  • 实体位于 App \ Entity \ Dba 文件夹中
  • 与数据库B相关的
  • 实体位于 App \ Entity \ Dbb 文件夹中
  • 与数据库C相关的
  • 实体位于 App \ Entity \ Dbc 文件夹中

使用flex, doctrine.yaml 文件中的学说配置如下所示:

doctrine:
    dbal:
        default_connection: a
        connections:
            a:
                driver:   '%database_a_driver%'
                url: '%env(DATABASE_A_URL)%'
                charset:  UTF8
                server_version: '%server_version%'
            b:
                driver:   '%database_b_driver%'
                url: '%env(DATABASE_B_URL)%'
                charset:  UTF8
                server_version: '%server_version%'
            c:
                driver:   '%database_c_driver%'
                url: '%env(DATABASE_C_URL)%'
                charset:  UTF8
                server_version: '%server_version%'
    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        default_entity_manager: em_a

        entity_managers:
            em_a:
                connection: a
                mappings:
                    AppDba:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/Dba'
                        prefix: 'App\Entity'
                        alias: AppDba
            em_b:
                connection: b
                    AppDbb:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/Dbb'
                        prefix: 'App\Entity'
                        alias: AppDbb
            em_c:
                connection: c
                    AppDbc:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/Dbc'
                        prefix: 'App\Entity'
                        alias: AppDbc

现在是问题了。

当我运行此命令时:

  

bin / console原则:数据库:create --connection = a

将使用正确的名称创建相应的数据库,并且还将创建默认的空公共模式。这是正常的,因为我还没有执行doctrine:schema:create --em=em_a命令。

但是也有一个架构,其中还创建了一些表。而且此架构不属于 a 数据库,但属于 b 数据库。奇怪的是,此意外模式内的那些表未在我的应用程序的任何映射中进行配置。它们仅在现有数据库中。

有人知道这个问题的根源以及如何解决吗?

其他信息:

  • Symfony 3.3.18
  • PostgreSQL 9.4.17
  • 教义2.5.9稳定
  • doctrine dbal v2.6.3
  • 教义包1.9.1

1 个答案:

答案 0 :(得分:0)

因此,感谢DonCallistoiiirxs我解决了这个问题。我输入了正确的前缀,并且我正在使用 url 设置键进行dbal连接。如果对我的问题有帮助,我不会。

这里是配置:

doctrine:
dbal:
    default_connection: a
    connections:
        a:
            driver:   '%database_a_driver%'
            url: '%env(DATABASE_A_URL)%'
            charset:  UTF8
            server_version: '%server_version%'
        b:
            driver:   '%database_b_driver%'
            url: '%env(DATABASE_B_URL)%'
            charset:  UTF8
            server_version: '%server_version%'
        c:
            driver:   '%database_c_driver%'
            url: '%env(DATABASE_C_URL)%'
            charset:  UTF8
            server_version: '%server_version%'
orm:
    auto_generate_proxy_classes: '%kernel.debug%'
    default_entity_manager: em_a

    entity_managers:
        em_a:
            connection: a
            mappings:
                AppDba:
                    is_bundle: false
                    type: annotation
                    dir: '%kernel.project_dir%/src/Entity/Dba'
                    prefix: 'App\Entity\Dba'
                    alias: AppDba
        em_b:
            connection: b
                AppDbb:
                    is_bundle: false
                    type: annotation
                    dir: '%kernel.project_dir%/src/Entity/Dbb'
                    prefix: 'App\Entity\Dbb'
                    alias: AppDbb
        em_c:
            connection: c
                AppDbc:
                    is_bundle: false
                    type: annotation
                    dir: '%kernel.project_dir%/src/Entity/Dbc'
                    prefix: 'App\Entity\Dbc'
                    alias: AppDbc

此外,也许与托管Postgres数据库的docker容器存在一些同步问题,我删除了该容器,然后再次创建了它。因此,现在我没有任何未在映射配置中配置的意外模式和表。

最后一件事,当使用bin/console doctrine:database:create --env=test --connection=a时,预期结果是应在没有任何模式和表的情况下创建数据库。然后,在运行bin/console doctrine:create:schema --em=em_a --env=test时,它应该根据您的映射和配置创建所有架构和表。

但是Postgres数据库必须始终具有默认的 public 。因此,在创建具有学说的数据库时,将创建此架构。没有任何表,它将是空的,但是它将在那里。我猜这是与postgres驱动程序有关的特定行为。因此,在使用准则创建架构和表之前,必须手动删除此 public 架构,否则,将触发此错误:

  

Schema-Tool失败,错误为'执行'CREATE SCHEMA public'时发生异常:
                                                                                                                       SQLSTATE [42P06]:模式重复:7错误:执行DDL时模式“ public”已存在”:CREATE SCHEMA public

也许有一个允许自动执行此操作的设置,但我不知道。欢迎任何建议。