Допустим, у меня есть таблица представлений. И я хочу получить данные от него к сущности. Могу ли я (и как) создать класс сущности для этого. (не требуется операция сохранения). Я просто хочу их отобразить.
Как настроить объект (доктрину) для представления базы данных в Symfony 2
Ответ 1
В запросе представления нет ничего особенного - это просто виртуальная таблица. Настройте таблицу своего объекта таким образом и наслаждайтесь:
/**
* @ORM\Entity
* @ORM\Table(name="your_view_table")
*/
class YourEntity {
// ...
}
Ответ 2
Принятый ответ правильный, но я хотел бы предложить несколько дополнительных предложений, которые вы можете рассмотреть:
Отметьте свою сущность как доступную только для чтения.
Сделать конструктор закрытым, чтобы только экземпляры Doctrine могли создавать экземпляры.
/**
* @ORM\Entity(readOnly=true)
* @ORM\Table(name="your_view_table")
*/
class YourEntity {
private function __construct() {}
}
Ответ 3
Оба предыдущих ответа верны, но если вы используете инструмент миграции доктрины и выполните schema:update
, он не сработает...
Итак, помимо маркировки объекта как только для чтения и создания закрытого конструктора (объясняется в ответе Иана Филлипса):
/**
* @ORM\Entity(readOnly=true)
* @ORM\Table(name="your_view_table")
*/
class YourEntity {
private function __construct() {}
}
Вам нужно будет установить инструмент схемы для игнорирования объекта при выполнении схемы: update...
Для этого вам просто нужно создать эту команду в своем пакете и установить объект yout в списке ignoredEntity:
ЦСИ/Acme/CoreBundle/Command/DoctrineUpdateCommand.php:
<?php
namespace Acme\CoreBundle\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\Tools\SchemaTool;
class DoctrineUpdateCommand extends \Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand {
protected $ignoredEntities = array(
'Acme\CoreBundle\Entity\EntityToIgnore'
);
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas) {
/** @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
$newMetadatas = array();
foreach ($metadatas as $metadata) {
if (!in_array($metadata->getName(), $this->ignoredEntities)) {
array_push($newMetadatas, $metadata);
}
}
parent::executeSchemaCommand($input, $output, $schemaTool, $newMetadatas);
}
}
(кредит Александру Трандафиру Каталину: полученный здесь: fooobar.com/questions/400283/...)
Кстати, это единственный способ, которым я нашел работу с представлениями из доктрины... Я знаю, что это обходной путь... Если есть лучший способ, я открыт или предложения)
Ответ 4
В дополнение к вышеперечисленным, если вы используете миграции доктрины для обновления схемы, следующая конфигурация работает отлично.
/**
* @ORM\Entity(readOnly=true)
* @ORM\Table(name="view_table_name")
*/
class YourEntity {
private function __construct() {}
}
До сих пор те же, что и выше. Здесь вам нужно настроить доктрину, чтобы она не привязывала схемы;
doctrine:
dbal:
schema_filter: ~^(?!view_)~
Приведенное выше определение фильтра фильтрует все префиксные таблицы 'view_', а также представления, которые могут быть расширены с помощью regex. Просто убедитесь, что вы назвали свои представления префиксом "view_".
Но doctrine: schema: update --dump-sql по-прежнему показывает представления, я надеюсь, что они тоже будут интегрировать один и тот же фильтр в обновление схемы.
Я надеюсь, что это решение поможет некоторым другим.
Источник: http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html#manual-tables
Ответ 5
В дополнение к вышеуказанному ответу, я смешал некоторые из вашего примера кода, чтобы расширить DoctrineUpdateCommand
Это мой DoctrineUpdateCommand:
class DoctrineUpdateCommand extends UpdateSchemaDoctrineCommand{
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas) {
$container = $this->getApplication()->getKernel()->getContainer();
$filterExpr = $container->get('doctrine')->getEntityManager()->getConnection()->getConfiguration()->getFilterSchemaAssetsExpression();
$emptyFilterExpression = empty($filterExpr);
/** @var $newMetadatas \Doctrine\ORM\Mapping\ClassMetadata */
$newMetadatas = array();
foreach ($metadatas as $metadata) {
if(($emptyFilterExpression||preg_match($filterExpr, $metadata->getTableName()))){
array_push($newMetadatas, $metadata);
}
}
parent::executeSchemaCommand($input, $output, $schemaTool, $newMetadatas);
}
}
Спасибо за правильный путь