运行架构管理器更新时忽略Doctrine2实体

时间:2012-09-24 10:18:39

标签: doctrine-orm

我已经定义了一个Doctrine Entity,它映射到我的数据库中的View。一切正常,实体关系按预期正常工作。

现在的问题是,当在CLI上运行orm:schema-manager:update时,会为此实体创建一个表,这是我想要阻止的。已经存在此实体的视图,无需为其创建表。

我是否可以注释实体,以便在仍然保持对所有实体相关功能(关联,......)的访问权限时不会创建表?

5 个答案:

答案 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)

相当旧,但使用Doctrine2postGenerateSchema事件监听器也没有任何价值解决方案 - 对我而言,它比覆盖更好 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命令时,为什么不是最简单的方法:

  1. 从@ORM \ Entity annotation中删除@
  2. 执行doctrine:schema:update
  3. 将@添加到ORM \ Entity注释
  4. - )