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

Chr*_*isR 10 doctrine-orm

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

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

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

Ale*_*lin 15

基于在Marco Pivetta的帖子中启发的ChrisR的原始alswer我在这里添加了解决方案,如果你使用Symfony2:

看起来Symfony2不使用原始Doctrine命令:\ Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand

相反,它使用捆绑中的一个:\ Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand

所以基本上这是必须扩展的类,最终有:

SRC /阿克米/ 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);
  }

}
Run Code Online (Sandbox Code Playgroud)


Chr*_*isR 7

最终它非常简单,我只需将其子类\Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand化为我自己的CLI命令.在该子类中过滤$metadatas传递给executeSchemaCommand()它的数组,然后将其传递给父函数.

只需将这个新的子类命令附加到您在doctrine cli脚本中使用的ConsoleApplication并完成!

下面是扩展命令,在生产中你可能想$ignoredEntities从你的配置或东西中获取属性,这应该会让你顺利.

<?php
use Symfony\Component\Console\Input\InputArgument,
    Symfony\Component\Console\Input\InputOption,
    Symfony\Component\Console\Input\InputInterface,
    Symfony\Component\Console\Output\OutputInterface,
    Doctrine\ORM\Tools\SchemaTool;

class My_Doctrine_Tools_UpdateCommand extends \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand
{
    protected $name = 'orm:schema-tool:myupdate';

    protected $ignoredEntities = array(
        'Entity\Asset\Name'
    );

    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);
            }
        }

        return parent::executeSchemaCommand($input, $output, $schemaTool, $newMetadatas);
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:为了让我走上正轨,可以归功于Marco Pivetta.https://groups.google.com/forum/?fromgroups=#!topic/doctrine-user/rwWXZ7faPsA

  • 此解决方案可防止外键指向被忽略的实体. (2认同)

小智 6

在 Doctrine 2.7.0 中引入了新的SchemaIgnoreClasses实体管理器配置选项,该选项基本上忽略任何模式操作中配置的类。

要与 Symfony 一起使用它,我们只需schema_ignore_classes在 Doctrine 实体管理器配置中添加密钥,如下所示:

doctrine:
    dbal:
        # your dbal configuration
    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                mappings:
                    Main:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/Main'
                        prefix: 'App\Entity\Main'
                        alias: Main
                schema_ignore_classes:
                    - Reference\To\My\Class
                    - Reference\To\My\OtherClass

Run Code Online (Sandbox Code Playgroud)


Kam*_*nek 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);
            }

        }
    }

}
Run Code Online (Sandbox Code Playgroud)

还注册监听器:

ignore_tables_listener:
    class: AppBundle\EventListener\IgnoreTablesListener
    tags:
        - {name: doctrine.event_listener, event: postGenerateSchema }
Run Code Online (Sandbox Code Playgroud)

不需要额外的钩子.

  • 是的,但只创建(生成)`Schema`实例 - 未执行.在这种情况下,`dropTable`表示从`Schema`实例中取消设置表.如果你调用:`d:s:u --dump-sql`,你将收到生成的模式SQL,而不会忽略表. (2认同)
  • 如果您的架构没有错误,则此解决方案更好。它允许外键指向被忽略的东西。但是我需要忽略只是因为许多实体存在一些特定的错误,所以我想跳过它们。** PS:**我遇到了您的博客@KamilAdryjanek,您应该删除实体管理器的依赖项调用。给定循环参考误差。相反,$ args参数已经具有getEntityManager方法。 (2认同)