Соединение с базой данных для чтения реплики никогда не использовалось, возвращается к значениям по умолчанию
Я слежу за документацией здесь https://symfony.com/doc/current/reference/configuration/doctrine.html о настройке альтернативных подключений к базе данных с целью репликации чтения. Для справки я использую AWS Aurora PostgreSQL с конечными точками для основного и только для чтения.
Я установил это для своего
doctrine.yaml
doctrine:
dbal:
default_connection: default
connections:
default:
url: '%env(resolve:DATABASE_URL)%'
read:
url: '%env(resolve:READ_URL)%'
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
dql:
datetime_functions:
date_trunc: App\DoctrineExtensions\DateTrunc
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
read:
connection: read
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: false
dql:
datetime_functions:
date_trunc: App\DoctrineExtensions\DateTrunc
mappings:
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
auto_generate_proxy_classes: true
И вызывая orm только для чтения как:
$user = $this->getDoctrine()->getRepository(User::class, 'read')->findOneBy(['email' => $payload['email']]);
Например.
Если я назову это, он все равно попадет в базу данных по умолчанию. Если я неправильно назову его, Symfony выдает исключение, как и ожидалось, поэтому я могу подтвердить, что конфигурация подобрана и загружается правильно.
Как моя конфигурация или вызов неверны, что он все еще запрашивает у
default
подключение к базе данных или есть лучший способ определить реплики чтения для подключения к данным? Я не нашел для него никакой текущей документации.
1 ответ
Согласно этому:
Один объект может управляться более чем одним менеджером объекта. Однако это приводит к неожиданному поведению при расширении из ServiceEntityRepository в вашем настраиваемом репозитории. ServiceEntityRepository всегда использует настроенный диспетчер сущностей для этой сущности. Чтобы исправить эту ситуацию, вместо этого расширьте EntityRepository и больше не полагайтесь на автоматическое подключение:
Поэтому вы должны убедиться, что ваш репозиторий расширяется
EntityRepository
вместо
ServiceEntityRepository
.
Тогда вы должны теперь всегда получать этот репозиторий, используя
ManagerRegistry::getRepository()
.
Так что в основном это будет работать, так как
$this->getDoctrine()
вернуть экземпляр
ManagerRegistry
.
$user = $this->getDoctrine()->getRepository(User::class, 'read')->findOneBy(['email' => $payload['email']]);
Обратной стороной является то, что вы не сможете использовать автоподключение для самого репозитория.
Таким образом, это не сработает, если вы не передадите этот репозиторий вручную.
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}