我已经定义了一个Doctrine Entity,它映射到我的数据库中的View。一切正常,实体关系按预期正常工作。
现在的问题是,当在CLI上运行orm:schema-manager:update
时,会为此实体创建一个表,这是我想要阻止的。已经存在此实体的视图,无需为其创建表。
我是否可以注释实体,以便在仍然保持对所有实体相关功能(关联,......)的访问权限时不会创建表?
答案 0 :(得分:15)
基于在Marco Pivetta的帖子中启发的ChrisR的原始alswer我在这里添加了解决方案,如果你使用Symfony2:
看起来Symfony2在以下位置不使用原始的Doctrine命令: \学说\ ORM \工具\控制台\命令\ SchemaTool \更新命令
相反,它使用捆绑中的那个: \学说\捆绑\ DoctrineBundle \命令\代理\ UpdateSchemaDoctrineCommand
所以基本上这是必须扩展的类,最后有:
的src / Acme公司/ CoreBundle /命令/ 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);
}
}
答案 1 :(得分:7)
最终它非常简单,我只需要将\Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand
子类化到我自己的CLI命令中。在该子类中过滤要传递给$metadatas
的{{1}}数组,然后将其传递给父函数。
将这个新的子类命令附加到您在doctrine cli脚本中使用的ConsoleApplication并完成!
下面是扩展命令,在生产中你可能想要从你的配置或其他东西中获取executeSchemaCommand()
属性,这应该会让你顺利进行。
$ignoredEntities
PS:为了让我走上正轨,可以归功于Marco Pivetta。 https://groups.google.com/forum/?fromgroups=#!topic/doctrine-user/rwWXZ7faPsA
答案 2 :(得分:5)
相当旧,但使用Doctrine2
:postGenerateSchema
事件监听器也没有任何价值解决方案 - 对我而言,它比覆盖更好
Doctrine
课程:
namespace AppBundle\EventListener;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
/**
* IgnoreTablesListener class
*/
class IgnoreTablesListener
{
private $ignoredTables = [
'table_name_to_ignore',
];
public function postGenerateSchema(GenerateSchemaEventArgs $args)
{
$schema = $args->getSchema();
$tableNames = $schema->getTableNames();
foreach ($tableNames as $tableName) {
if (in_array($tableName, $this->ignoredTables)) {
// remove table from schema
$schema->dropTable($tableName);
}
}
}
}
同时注册听众:
ignore_tables_listener:
class: AppBundle\EventListener\IgnoreTablesListener
tags:
- {name: doctrine.event_listener, event: postGenerateSchema }
不需要额外的钩子。
答案 3 :(得分:0)
$schema->getTableNames()
无效(我不知道为什么)。
所以:
namespace AppBundle\EventListener;
use Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand;
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
class IgnoreTablesListener extends UpdateSchemaDoctrineCommand
{
private $ignoredEntities = [
'YourBundle\Entity\EntityYouWantToIgnore',
];
/**
* Remove ignored tables /entities from Schema
*
* @param GenerateSchemaEventArgs $args
*/
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)) {
// remove table from schema
$schema->dropTable($table->getName());
}
}
}
}
注册服务
#services.yml
ignore_tables_listener:
class: AppBundle\EventListener\IgnoreTablesListener
tags:
- {name: doctrine.event_listener, event: postGenerateSchema }
工作得很好! ;)
答案 4 :(得分:-1)
如果问题只是在db_view中产生错误,那么在调用doctrine:schema:update命令时,为什么不是最简单的方法:
- )