У меня есть сущность, использующая базу данных, отличную от той, которая используется в соединении по умолчанию, поэтому в аннотации сущности я поместил:
/**
* MyClassName
*
* @ORM\Table(name = "mytable", schema = "`myschema`")
* @ORM\Entity(repositoryClass = "App\...\MyClassNameRepository")
*/
class MyClassName
{
...
Это работает.
Но я бы хотел установить такую схему:
schema = "`%myapp.specificschema%`"
Я хочу сделать это, потому что я хочу установить другое имя базы данных в производстве и среде, и я хочу изменить этот параметр только один раз только в одном файле. Но это кажется невозможным, потому что доктрина не может получить доступ к параметрам ...
Заранее благодарим за любой ответ!
Думаю, вам придется перейти с аннотаций на xml
Я протестировал xml вместо аннотации, он не работает лучше ... Может быть, мне стоит использовать другой диспетчер сущностей, но это часть работы ...
Боф, лучше не работает ...
@Coolhand, как вы указываете в своем удаленном сообщении, что мой ответ работает, пожалуйста, примите его;)






Вы можете изменить схему с помощью Doctrine loadMetadata Event.
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#load-classmetadata-event
Например, с шаблоном подписчика у нас должно получиться что-то вроде этого:
parameters.yml
parameters:
schema_name: "my_schema_name"
services.yml
doctrine.schema_name.subscriber:
class: App\Doctrine\SchemaDoctrineSubscriber
arguments: ["%schema_name%"]
tags:
- { name: doctrine.event_subscriber, connection: default }
И соответствующий класс:
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
class SchemaDoctrineSubscriber implements EventSubscriber
{
/** @var string */
private $schemaName;
/**
* SchemaDoctrineSubscriber constructor.
* @param string $schemaName
*/
public function __construct(string $schemaName)
{
$this->schemaName = $schemaName;
}
/**
* @inheritdoc
*/
public function getSubscribedEvents()
{
return array(
'loadClassMetadata',
);
}
/**
* @param LoadClassMetadataEventArgs $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
if ($classMetadata->getTableName() === 'mytable') {
$classMetadata->table['schema'] = $this->schemaName;
}
}
}
Затем вы можете оставить свойство schema пустым в аннотации, событие установит для него хорошее значение.
для меня после того, как я следую этому коду. схема все еще не изменилась. Но после установки вручную с помощью аннотаций, успешное изменение схемы. После проверки внутри $classMetadata схема была изменена, но она не будет работать на моем symfony.
Обновление с n3k answer для управления AssociationMappings
-- Юридическое лицо--
/**
* @ORM\Table(schema = "primary", name = "**table_entity_name**", ...)
* @ORM\Entity
*/
class Entity
{
/**
* @ORM\ManyToMany(targetEntity = "**path\To\Entity\ManyToMany**" ...)
* @ORM\JoinTable(
* schema = "secondary",
* name = "**table_field_name**",
* joinColumns = {@ORM\JoinColumn(name = "fk_join_***", referencedColumnName = "id")},
* inverseJoinColumns = {@ORM\JoinColumn(name = "fk_inverse_***", referencedColumnName = "id")}
* )
*/
private $fieldManyToMany ;
}
- SchemaDoctrineSubscriber -
!! getEnvSchemaName () предназначен для быстрого управления именами схем
<?php
namespace AppBundle\Doctrine ;
use Doctrine\Common\EventSubscriber ;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs ;
/**
* Permet de modifier les noms des tables (schemas) depuis les paramètres
*/
class SchemaDoctrineSubscriber implements EventSubscriber
{
/**
* Nom des schemas
*
* string
*/
private $schema_primary ;
private $schema_secondary ;
/**
*
* @param string $schema_primary
* @param string $schema_secondary
*/
public function __construct($schema_primary, $schema_secondary)
{
$this->schema_primary = $schema_primary ;
$this->schema_secondary = $schema_secondary ;
}
/**
* @inheritdoc
*/
public function getSubscribedEvents()
{
return ['loadClassMetadata'] ;
}
/**
* @param LoadClassMetadataEventArgs $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata() ;
// Modifie les schemas des AssociationMappings de l'entité
foreach ($classMetadata->getAssociationMappings() as $key => $associationMapping)
if (isset($associationMapping['joinTable']))
{
$associationMapping['joinTable']['schema'] = $this->getEnvSchemaName($classMetadata->getSchemaName()) ;
$classMetadata->setAssociationOverride($key, $associationMapping) ;
}
// Modifie le schema de l'entité
$classMetadata->table['schema'] = $this->getEnvSchemaName($classMetadata->getSchemaName()) ;
}
/**
* Retourne le nom du schema de l'environnement
*
* @param string $classMetadataSchemaName
*
* @return string
*/
private function getEnvSchemaName($classMetadataSchemaName)
{
switch ($classMetadataSchemaName)
{
case 'primary':
return $this->schema_primary ;
case 'secondary':
return $this->schema_secondary ;
}
}
}
Services.yml
# Permet de modifier les noms des tables (schemas) depuis les paramètres
doctrine.schema_name.subscriber:
class: AppBundle\Doctrine\SchemaDoctrineSubscriber
arguments: ["%databases.primary.schema.name%", "%databases.secondary.schema.name%"]
tags:
- { name: doctrine.event_subscriber, connection: **main_connection** }
Parameters.yml
parameters:
databases.primary.schema.name: **primary_schema_name**
databases.secondary.schema.name: **secondary_schema_name**
Можете ли вы показать нам свой файл конфигурации config.yml