假设我有一个视图表。我想从它获取数据到一个实体。我可以(以及如何)创建实体类来实现这一点(不需要保存操作)吗?我只想显示它们。
e0bqpujr1#
公认的答案是正确的,但我想提供一些额外的建议,你可能想考虑:将实体标记为只读。将构造函数设为私有,这样只有Doctrine可以创建示例。
/** * @ORM\Entity(readOnly=true) * @ORM\Table(name="your_view_table") */ class YourEntity { private function __construct() {} }
vlf7wbxs2#
查询视图没有什么特别的-它只是一个虚拟表。以这种方式设置实体的表并享受:
/** * @ORM\Entity * @ORM\Table(name="your_view_table") */ class YourEntity { // ... }
2skhul333#
除了上面的回答,如果你正在使用原则迁移进行模式更新,下面的配置可以很好地工作。
/** * @ORM\Entity(readOnly=true) * @ORM\Table(name="view_table_name") */ class YourEntity { private function __construct() {} }
到这里和上面的答案一样,这里需要配置原则不绑定模式;
doctrine: dbal: schema_filter: ~^(?!view_)~
上面的过滤器定义过滤了所有以'view_'为前缀的表以及可以使用正则表达式扩展的视图。只要确保你用'view_'前缀命名你的视图。但是doctrine:schema:update --dump-sql仍然显示视图,我希望他们也能将相同的过滤器集成到模式更新中。我希望这个解决方案能帮助其他人。来源:http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html#manual-tables
ha5z0ras4#
前面的两个答案都是正确的,但是如果你使用教义迁移工具并执行schema:update,它将失败。因此,除了将实体标记为只读并使构造函数私有(在Ian菲利普斯的回答中解释):
schema:update
你需要设置schema工具在执行schema时忽略实体:update.为了做到这一点,你只需要在你的bundle中创建这个命令,并在MyRedEntity列表中设置yout实体:src/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); } }
(图片来源:Alexandru Trandafir Catalin)顺便说一句,这是我发现的唯一方法来处理来自教义的观点......我知道这是一个变通方案......如果有更好的方法,我是开放的或建议)
knpiaxh15#
除了上面的答案,你必须有一个命名策略,你的视图的实体和虚拟表,例如:view_your_table,然后你必须添加以下代码到doctrine.yaml,以禁止创建新的迁移文件到视图:schema_filter: ~^(?!view_)~
schema_filter: ~^(?!view_)~
okxuctiv6#
除了上面的答案,我还混合了一些示例代码来扩展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); } }
谢谢你走对了路
ny6fqffe7#
我花了一天的时间在这上面,因为需要在我的数据库中引入一个关于Zend实现的视图。如前所述,你应该创建一个实体,这个实体必须有Id()注解:
Id()
/** * @Doctrine\ORM\Mapping\Table(name="your_view") * @Doctrine\ORM\Mapping\Entity(readOnly=true) */ class YourViewEntity { /** * @var SomeEntityInterface * @Doctrine\ORM\Mapping\Id() * @Doctrine\ORM\Mapping\OneToOne(targetEntity="SomeMainEntity", fetch="LAZY") * @Doctrine\ORM\Mapping\JoinColumn(nullable=false, referencedColumnName="id") */ protected $some; /** * @var AnotherEntityInterface * @Doctrine\ORM\Mapping\ManyToOne(targetEntity="AnotherEntity", fetch="LAZY") * @Doctrine\ORM\Mapping\JoinColumn(nullable=false, referencedColumnName="id") */ protected $another; // Make the constructor private so that only Doctrine can create instances. private function __construct() {} }
也可以使用Ian Phillips answer中描述的私有构造函数。然而,这并不能阻止orm:schema-tool:update基于新实体创建一个表,试图覆盖我们的视图......尽管在生产环境中应该避免使用orm:schema-tool:update,而应该使用迁移脚本,但对于开发目的来说,这是非常有用的。由于schema_filter: ~^(?!view_)~似乎都不工作,也弃用,我设法找到了一个技巧Kamil Adryjanek page,提出了一个选项,以添加一个EventListener或Subscriber到实体管理器,这将防止为我们创建表.矿山实现如下:
orm:schema-tool:update
EventListener
Subscriber
class SkipAutogenerateTableSubscriber implements EventSubscriber { public const CONFIG_KEY = "skip_autogenerate_entities"; private $ignoredEntities = []; public function __construct($config) { if (array_key_exists(self::CONFIG_KEY, $config)) { $this->ignoredEntities = (array) $config[self::CONFIG_KEY]; } } public function getSubscribedEvents() { return [ ToolEvents::postGenerateSchema ]; } public function postGenerateSchema(GenerateSchemaEventArgs $args) { $schema = $args->getSchema(); $em = $args->getEntityManager(); $ignoredTables = []; foreach ($this->ignoredEntities as $entityName) { $ignoredTables[] = $em->getClassMetadata($entityName)->getTableName(); } foreach ($schema->getTables() as $table) { if (in_array($table->getName(), $ignoredTables)) { $schema->dropTable($table->getName()); } } } }
这不仅解决了orm:schema-tool的问题,而且解决了doctrine/migrations模块的migrations:diff的问题。
orm:schema-tool
doctrine/migrations
migrations:diff
7条答案
按热度按时间e0bqpujr1#
公认的答案是正确的,但我想提供一些额外的建议,你可能想考虑:
将实体标记为只读。
将构造函数设为私有,这样只有Doctrine可以创建示例。
vlf7wbxs2#
查询视图没有什么特别的-它只是一个虚拟表。以这种方式设置实体的表并享受:
2skhul333#
除了上面的回答,如果你正在使用原则迁移进行模式更新,下面的配置可以很好地工作。
到这里和上面的答案一样,这里需要配置原则不绑定模式;
上面的过滤器定义过滤了所有以'view_'为前缀的表以及可以使用正则表达式扩展的视图。只要确保你用'view_'前缀命名你的视图。
但是doctrine:schema:update --dump-sql仍然显示视图,我希望他们也能将相同的过滤器集成到模式更新中。
我希望这个解决方案能帮助其他人。
来源:http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html#manual-tables
ha5z0ras4#
前面的两个答案都是正确的,但是如果你使用教义迁移工具并执行
schema:update
,它将失败。因此,除了将实体标记为只读并使构造函数私有(在Ian菲利普斯的回答中解释):
你需要设置schema工具在执行schema时忽略实体:update.
为了做到这一点,你只需要在你的bundle中创建这个命令,并在MyRedEntity列表中设置yout实体:
src/Acme/CoreBundle/Command/DoctrineUpdateCommand.php:
(图片来源:Alexandru Trandafir Catalin)
顺便说一句,这是我发现的唯一方法来处理来自教义的观点......我知道这是一个变通方案......如果有更好的方法,我是开放的或建议)
knpiaxh15#
除了上面的答案,你必须有一个命名策略,你的视图的实体和虚拟表,例如:view_your_table,然后你必须添加以下代码到doctrine.yaml,以禁止创建新的迁移文件到视图:
schema_filter: ~^(?!view_)~
okxuctiv6#
除了上面的答案,我还混合了一些示例代码来扩展DoctrineUpdateCommand
这是我的DoctrineUpdateCommand:
谢谢你走对了路
ny6fqffe7#
我花了一天的时间在这上面,因为需要在我的数据库中引入一个关于Zend实现的视图。
如前所述,你应该创建一个实体,这个实体必须有
Id()
注解:也可以使用Ian Phillips answer中描述的私有构造函数。然而,这并不能阻止
orm:schema-tool:update
基于新实体创建一个表,试图覆盖我们的视图......尽管在生产环境中应该避免使用orm:schema-tool:update
,而应该使用迁移脚本,但对于开发目的来说,这是非常有用的。由于
schema_filter: ~^(?!view_)~
似乎都不工作,也弃用,我设法找到了一个技巧Kamil Adryjanek page,提出了一个选项,以添加一个EventListener
或Subscriber
到实体管理器,这将防止为我们创建表.矿山实现如下:这不仅解决了
orm:schema-tool
的问题,而且解决了doctrine/migrations
模块的migrations:diff
的问题。