Создание нескольких баз данных с доктриной на основе нескольких подключений

Я столкнулся с проблемой при создании нескольких баз данных на основе нескольких подключений для целей функционального тестирования.

Я создал на Приложение Symfony 3.3 из-за некоторых ограничений, и будет запланировано обновление поддерживаемой версии Symfony. Следует иметь в виду, что мне приходилось иметь дело с существующей базой данных PostgreSQL, особенно с 3 базами данных:

  • база данных A
  • база данных B
  • база данных C

Мне не нравится разрабатывать свое приложение на основе существующей базы данных. Обычно, когда я создаю приложение с нуля, я сначала разрабатываю свое приложение и все бизнес-правила, но здесь у меня не было выбора. Звучит плохо, но эта часть моего приложения создана на основе существующей базы данных. В любом случае приветствуются любые предложения. Итак, в папке Приложение \ Сущность я настроил сопоставление для 3 подключений:

  • сущности, относящиеся к базе данных A, находятся в папке Приложение \ Сущность \ Dba
  • сущности, относящиеся к базе данных B, находятся в папке Приложение \ Сущность \ Dbb
  • сущности, относящиеся к базе данных C, находятся в папке Приложение \ Сущность \ 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 doctrine:database:create --connection=a

Соответствующая база данных создается с правильным именем, а также создается пустая общедоступная схема по умолчанию. Это нормально, потому что я еще не выполнил команду doctrine:schema:create --em=em_a.

Но есть также схема с некоторыми таблицами внутри, которые также создаются. И эта схема не принадлежит базе данных а, но принадлежит базе данных б. И что странно, эти таблицы внутри этой неожиданной схемы не настроены ни в одном сопоставлении в моем приложении. Они есть только в существующей базе.

Кто-нибудь знает причину возникновения этой проблемы и как ее решить?

Дополнительная информация:

  • Symfony 3.3.18
  • PostgreSQL 9.4.17
  • Доктрина Орм 2.5.9-стабильная
  • доктрина dbal v2.6.3
  • пакет доктрин 1.9.1

Вы устанавливаете все сопоставления для подключения a, так чего же вы ожидали от этого?

DonCallisto 19.09.2018 11:31

@DonCallisto Я отредактировал вопрос, я забыл некоторые ключи конфигурации

fgamess 19.09.2018 11:37

prefix здесь записаны так, как вы их написали в приложении, или у вас есть там ошибки "вставки"? Потому что я полагаю, это должны быть App\Entity\Dba, App\Entity\Dbb, App\Entity\Dbc

DonCallisto 19.09.2018 11:49

@DonCallisto То же самое и в приложении. Так вы думаете, что проблема должна исходить из этого? В этом случае, как вы можете объяснить создание таблиц и схем, которые не являются частью какого-либо сопоставления в моем приложении?

fgamess 19.09.2018 11:51

Полагаю, это связано с разделом mappings. Я, конечно, пытаюсь угадать, так как я не очень осведомлен об этой проблеме, иначе я бы ответил на вопрос. Кстати, измените префикс и попробуйте еще раз: что вы получите?

DonCallisto 19.09.2018 11:54

Обязательно поменяйте префикс, иначе ничего не получится. Вам также следует очистить метаданные доктрины (php bin / console doctrine: cache: clear-metadata), если вы используете кеширование аннотаций доктрины.

iiirxs 19.09.2018 13:41

Я дам вам обратную связь. И я уже очистил метаданные кеша

fgamess 19.09.2018 13:46

iiirxs DonCallisto кажется, что он работает, когда я меняю префикс, как было предложено, а также напрямую использую URL-адрес базы данных. Я отправлю ответ, чтобы уточнить. Спасибо за помощь и потраченное время, ребята

fgamess 20.09.2018 10:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
956
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, благодаря ДонКаллисто и IIIRXS я исправил проблему. Я поставил правильный префикс, а также использую ключ настройки 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, я удалил контейнер, а затем создал его снова. Итак, теперь у меня нет неожиданной схемы и таблицы, которые не настроены в моей конфигурации сопоставления.

И последнее: при использовании bin/console doctrine:database:create --env=test --connection=a ожидаемый результат состоит в том, что база данных должна быть создана без каких-либо схем и таблиц. А затем при запуске bin/console doctrine:create:schema --em=em_a --env=test он должен создать все схемы и таблицы из вашего сопоставления и вашей конфигурации.

Но база данных Postgres всегда должна иметь значение общественный по умолчанию. Итак, при создании базы данных с доктриной эта схема будет создана. Он будет пустым без какой-либо таблицы, но он будет там. Я предполагаю, что это конкретное поведение, связанное с драйвером postgres. Поэтому перед использованием доктрины для создания схемы и таблиц необходимо вручную удалить эту схему общественный, иначе она вызовет эту ошибку:

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

Может быть, есть настройка, которая позволяет делать это автоматически, но я этого не знаю. Любые предложения приветствуются.

Другие вопросы по теме