Doctrine 2和MySQL:表和视图之间的关联映射

时间:2016-12-13 19:55:20

标签: php doctrine-orm model-associations sql-view

我正在努力创建2个entites之间的关联。左边是表格表示。右边是视图表示。

我刚刚成功地使这个关系工作,但是在使用php vendor/bin/doctrine orm:schema-tool:create创建模式时遇到了问题。

以下是试用它所需的所有代码:

SQL

CREATE TABLE IF NOT EXISTS `demo` (
  `id` int(11) NOT NULL,
  `name` varchar(30) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `demo` (`id`, `name`) VALUES
(1, 'demo 1'),
(2, 'demo 2'),
(3, 'demo 3'),
(4, 'demo 4');

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `demo_metadata` AS select `se`.`id` AS `demo_id`,12 AS `demo_count` from `demo` `se`;

演示表实体

/**
 * @Entity
 * @Table(name="demo")
 */
class Demo {

    /**
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
    private $id;

    /**
     * @Column(type="string", length=30)
     */
    private $name;

    /**
     * @OneToOne(targetEntity="DemoMetadata")
     * @JoinColumn(name="id", referencedColumnName="demo_id")
     */
    private $metadata;

    public function getMetadata() {
        return $this->metadata;
    }
}

演示视图实体

/**
 * @Entity
 * @Table(name="demo_metadata")
 */
class DemoMetadata {

    /**
     * @Id
     * @Column(type="integer")
     * @var int
     */
    private $demo_id;

    /**
     * @Column(type="integer")
     * @var int
     */
    private $demo_count;

    public function getDemoCount() {
        return $this->demo_count;
    }
}

查询和获取数据

$qb = $em->createQueryBuilder();
$qb
    ->select('d')
    ->from('Demo', 'd')
    ->leftJoin('d.metadata', 'dm')
    ->where('d.id = ?0')
    ->setParameter(0, 1);

$demo_object = $qb->getQuery()->getSingleResult();
var_dump($demo_object->getMetadata()->getDemoCount());

// display: int(12)

正如我们所看到的,Demo Entity的元数据属性使用视图中的数据填充。一切正常,并且符合预期。

但是使用这样的配置,当运行cli命令以删除模式,然后重新创建它时,会发生错误,因为demo_metadata表已经存在。

最后,我不是在寻找一种自动创建视图的方法。我有SQL脚本,我可以调用它来创建视图。我想知道是否有办法不尝试为某些实体创建表格?

[Doctrine\ORM\Tools\ToolsException]                                                                                                                                                                             
Schema-Tool failed with Error 'An exception occurred while executing 'CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8 _unicode_ci ENGINE = InnoDB':                                                                                                                                                                                   
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'demo_metadata' already exists' while executing DDL: CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB

这只是一个方便的问题,因为视图已经存在,并且不会被cli drop命令删除。

管理此问题的唯一方法是:

  1. drop schema(doctrine cli)
  2. 删除demo_metadata视图
  3. 创建架构(doctrine cli)
  4. 删除demo_metadata表格
  5. 创建demo_metadata视图
  6. 由于

    修改

    最后,我使用此代码过滤我需要的实体:

    <?php
    
    class UpdateSchema extends \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand {
    
        /**
         * {@inheritdoc}
         */
        protected function executeSchemaCommand(
            InputInterface $input, 
            OutputInterface $output, 
            SchemaTool $schemaTool, 
            array $metadatas) : int
        {
            $entities = array_filter($metadatas, function ($m) {
                return !$m->isReadOnly;
            });
            return parent::executeSchemaCommand($input, $output, $schemaTool, $entities);
        }
    }
    

1 个答案:

答案 0 :(得分:0)

除了globals()import re for name, value in globals().items(): if re.match(r'a[0-9]+', name): print 'found an a* variable:', name, value if re.match(r'b[0-9]+', name): print 'found a b* variable:', name, value 命令外,还有一个create命令。如果数据库已经存在,那就是你应该使用的那个

错误的答案,请参阅正确的评论