如何阻止学说尝试为已映射到实体上的视图创建表?

问题描述 投票:0回答:4

如何阻止 symfony 尝试为我在学说迁移中创建的视图创建表?

实体映射视图

/**
* Class TenancyPendingInspection
* @ORM\Entity(repositoryClass="DJABundle\PropertyVisit\Repository\TenancyPendingInspectionRepository", readOnly=true)
* @ORM\Table(name="view_tenancies_pending_inspections")
*/
class TenancyPendingInspection
{

我还有学说迁移文件。

学说配置

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                [...]
                charset:   UTF8
                server_version:       5.6
                schema_filter: ~^(?!view_)~

Doctirne 架构验证

php app/console doc:sch:val
[Mapping]  OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file.

教义架构更新

php app/console doc:sch:update --dump-sql
CREATE TABLE view_tenancies_pending_inspections ...
php symfony doctrine-orm
4个回答
5
投票

简短回答:这是不可能的。

发生这种情况是因为

MysqlPlatform
忽略了视图。

//vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php

class MySqlPlatform extends AbstractPlatform
[...]
    public function getListTablesSQL()
    {
         return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'";
    }
[...]

解决方案:创建一个不忽略视图的新MysqlPlatform:

class MysqlViewsPlatform extends \Doctrine\DBAL\Platforms\MySqlPlatform
{
    public function getListTablesSQL()
    {
        return "SHOW FULL TABLES";
    }
}

使用您的平台创建服务:

services:
    doctrine.dbal.mysql_views_platform:
        class: albertsola\DoctrineViews\MysqlViewsPlatform
        arguments: []

通过您的连接使用该平台:

doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   "%database_driver%"
                host:     "database_host%"
                port:     "database_port%"
                dbname:   "database_name%"
                user:     "database_user%"
                password: "database_password%"
                charset:   UTF8
                platform_service: "doctrine.dbal.mysql_views_platform"

应用程序/控制台学说:架构:验证 此命令验证实体和视图实体是否同步。

副作用: 应用程序/控制台学说:架构:更新--dump-sql 如果视图和实体不同步,这将生成不应执行的 SQL!您必须手动更新数据库中的视图。

我使用学说迁移来解决这个问题。尽管doctrine:schema:update --dump-sql对于检查它在您的视图/实体中不匹配的内容非常有用。

注意:此黑客停止创建表,但学说模式差异仍然尝试更新添加外键的“表”。


1
投票

这对我来说很有效;

class DiffCommandWrapper extends DiffCommand
{
    private $views = [];

    public function __construct(\PDO $db, SchemaProviderInterface $schemaProvider = null)
    {
        parent::__construct($schemaProvider);

        $name = $db->query('select database()')->fetchColumn();

        $stm = $db->query("SHOW FULL TABLES IN {$name} WHERE TABLE_TYPE LIKE 'VIEW';");

        foreach ($stm->fetchAll(\PDO::FETCH_ASSOC) as $row) {
            $this->views[] = $row["Tables_in_{$name}"];
        }
    }

    public function execute(InputInterface $input, OutputInterface $output)
    {
        $input->setOption('filter-expression', '/!(' . implode('|', $this->views) . ')/');
        parent::execute($input, $output);
    }
}

然后使用包装器代替 cli-config.php 中的 DiffCommand

ConsoleRunner::addCommands($cli);
$cli->addCommands([
    new something\DiffCommandWrapper($connection),
    new Command\ExecuteCommand(),
    new Command\GenerateCommand(),
    new Command\MigrateCommand(),
    new Command\StatusCommand(),
    new Command\VersionCommand(),
]);

0
投票

您应该能够使用 setFilterSchemaAssetsExpression。

http://www.doctrine-project.org/api/dbal/2.4/source-class-Doctrine.DBAL.Configuration.html#87-99

如果做不到这一点,如果您想做更少的编程和更多的配置,您可以将视图放入另一个实体管理器中。但这不是最好的方式......

https://symfony.com/doc/3.3/doctrine/multiple_entity_managers.html


0
投票

自doctrine-orm 2.11起,可以忽略选定的实体,请参阅此处

在doctrine yaml配置中你可以指定如下:

doctrine:
    orm:
        # ....
        schema_ignore_classes:
          - 'App\Entity\TenancyPendingInspection'
          - 'App\Entity\ViewToBeIngored'

© www.soinside.com 2019 - 2024. All rights reserved.