使用基于多个连接的学说创建多个数据库
Creating multiple databases with doctrine based on multiple connections
我在基于多个连接创建多个数据库以进行功能测试时遇到问题。
由于某些限制,我在 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 配置如下所示:
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 doctrine:database:create --connection=a
使用正确的名称创建了相应的数据库,并且还创建了空的默认 public 模式。这是正常的,因为我还没有执行doctrine:schema:create --em=em_a
命令。
但是也有一个模式,其中也创建了一些表。而这个模式不属于a数据库,而是属于b数据库。奇怪的是,在我的应用程序的任何映射中都没有配置这个意外模式中的那些表。它们仅在现有数据库中。
有谁知道这个问题的由来以及如何解决?
附加信息:
- Symfony 3.3.18
- PostgreSQL 9.4.17
- 条令 orm 2.5.9-稳定
- doctrine dbal v2.6.3
- 教义包 1.9.1
感谢 and 我解决了这个问题。我输入了正确的前缀,并且我正在使用 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 容器的一些同步问题有关,我删除了容器,然后重新创建了它。所以现在我没有任何未在我的映射配置中配置的意外架构和 table。
最后一件事,当使用 bin/console doctrine:database:create --env=test --connection=a
时,预期的结果是创建的数据库应该没有任何模式和 table。然后当 运行 bin/console doctrine:create:schema --em=em_a --env=test
它应该根据您的映射和配置创建所有模式和 table。
但 Postgres 数据库必须始终具有默认值 public。因此,当使用 doctrine 创建数据库时,将创建此模式。它将是空的,没有任何 table 但它会在那里。我想这是与 postgres 驱动程序相关的特定行为。所以在使用doctrine创建schema和tables之前,需要手动删除这个public schema,否则会触发这个错误:
Schema-Tool failed with Error 'An exception occurred while executing 'CREATE SCHEMA public':
SQLSTATE[42P06]: Duplicate schema: 7 ERROR: schema "public" already exists' while executing DDL: CREATE SCHEMA public
也许有一个允许自动执行此操作的设置,但我不知道。欢迎任何建议。
我在基于多个连接创建多个数据库以进行功能测试时遇到问题。
由于某些限制,我在 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 配置如下所示:
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 doctrine:database:create --connection=a
使用正确的名称创建了相应的数据库,并且还创建了空的默认 public 模式。这是正常的,因为我还没有执行doctrine:schema:create --em=em_a
命令。
但是也有一个模式,其中也创建了一些表。而这个模式不属于a数据库,而是属于b数据库。奇怪的是,在我的应用程序的任何映射中都没有配置这个意外模式中的那些表。它们仅在现有数据库中。
有谁知道这个问题的由来以及如何解决?
附加信息:
- Symfony 3.3.18
- PostgreSQL 9.4.17
- 条令 orm 2.5.9-稳定
- doctrine dbal v2.6.3
- 教义包 1.9.1
感谢
所以这里配置:
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 容器的一些同步问题有关,我删除了容器,然后重新创建了它。所以现在我没有任何未在我的映射配置中配置的意外架构和 table。
最后一件事,当使用 bin/console doctrine:database:create --env=test --connection=a
时,预期的结果是创建的数据库应该没有任何模式和 table。然后当 运行 bin/console doctrine:create:schema --em=em_a --env=test
它应该根据您的映射和配置创建所有模式和 table。
但 Postgres 数据库必须始终具有默认值 public。因此,当使用 doctrine 创建数据库时,将创建此模式。它将是空的,没有任何 table 但它会在那里。我想这是与 postgres 驱动程序相关的特定行为。所以在使用doctrine创建schema和tables之前,需要手动删除这个public schema,否则会触发这个错误:
Schema-Tool failed with Error 'An exception occurred while executing 'CREATE SCHEMA public':
SQLSTATE[42P06]: Duplicate schema: 7 ERROR: schema "public" already exists' while executing DDL: CREATE SCHEMA public
也许有一个允许自动执行此操作的设置,但我不知道。欢迎任何建议。