【问题标题】:Multiple DB Schema & migrations with Doctrine2 & PostgreSQL使用 Doctrine2 和 PostgreSQL 进行多数据库模式和迁移
【发布时间】:2015-12-29 16:22:11
【问题描述】:

我有一个包含多个模式的 PG 数据库。

我有一个 symfony2 应用程序,它只需要连接其中一个。

如果我没有配置任何东西,默认情况下,Doctrine2 会搜索所有模式,因此它会尝试在它不正确的表上创建 SELECT

我关注了这个答案:symfony2 + doctrine2@postgresql setting a schema

现在它似乎只出现在我指定的 shema 中,但它仍在寻找一些在我的架构中不存在但在其他架构中存在的表。

当我执行一些 ldoctrine:migrations:diff

[Doctrine\DBAL\DBALException]                                                                     
  An exception occurred while executing 'SELECT min_value, increment_by FROM "pgstatspacknameid"':  
  SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "pgstatspacknameid" does not exist           
  LINE 1: SELECT min_value, increment_by FROM "pgstatspacknameid"                                   
                                              ^                                                     

  [PDOException]                                                                           
  SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "pgstatspacknameid" does not exist  
  LINE 1: SELECT min_value, increment_by FROM "pgstatspacknameid"                          
                                              ^      

所以按照学说迁移文档,我在连接配置中添加了这一行:

        schema_filter: ~^(?!pgstats)~

它仍然总是尝试在那些表中创建SELECT...

【问题讨论】:

    标签: postgresql symfony pdo doctrine-orm schema


    【解决方案1】:

    迁移命令需要选项 --db-configuration。 它需要一个配置文件作为参数。 尝试使用配置文件的以下内容。

    <?php
    return array(
        "driverClass"=>"AppBundle\Driver",
        "host" => "localhost",
        "user" => "test",
        "password" => "test",
        "dbname" => "test"
            );
    ?>
    

    此外,我更改了 vendor/doctrine/dbal/lib/Doctrine/DBAL/SchemaPostgreSqlSchemaManager.php 以始终将模式添加到序列名称之前。

    像这样:

    /**
     * {@inheritdoc}
     */
    protected function _getPortableSequencesList($sequences)
    {
        $sequenceDefinitions = array();
        foreach ($sequences as $sequence) {//+ || true
            if ($sequence['schemaname'] != 'public' || true) {
                $sequenceName = $sequence['schemaname'] . "." . $sequence['relname'];
            } else {
                $sequenceName = $sequence['relname'];
            }
    
            $sequenceDefinitions[$sequenceName] = $sequence;
        }
        $list = array();
    
        foreach ($this->filterAssetNames(array_keys($sequenceDefinitions)) as $sequenceName) {
            $list[] = $this->_getPortableSequenceDefinition($sequenceDefinitions[$sequenceName]);
        }
        return $list;
    }
    
    /**
     * {@inheritdoc}
     */
    protected function getPortableNamespaceDefinition(array $namespace)
    {
        return $namespace['nspname'];
    }
    
    /**
     * {@inheritdoc}
     */
    protected function _getPortableSequenceDefinition($sequence)
    {//+ || true
        if ($sequence['schemaname'] != 'public' || true) {
            $sequenceName = $sequence['schemaname'] . "." . $sequence['relname'];
        } else {
            $sequenceName = $sequence['relname'];
        }
    
        $data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName));
    
        return new Sequence($sequenceName, $data[0]['increment_by'], $data[0]['min_value']);
    }
    

    (在假定架构名称 != 'public' 的地方添加了 or true 两个地方)

    【讨论】:

    • 谢谢我要测试这个解决方案!您知道如何在不更改 vendor 文件的情况下覆盖此类吗?
    • 未测试,但您可以从 AbstractPostgresqlDriver 覆盖 getSchemaManager 以返回具有上述更改的自定义 SchemaManager。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 2022-08-18
    • 2014-08-12
    • 1970-01-01
    相关资源
    最近更新 更多