【问题标题】:'Invalid schema name' error thrown by Doctrine, but the raw SQL seems to workDoctrine 抛出“无效的模式名称”错误,但原始 SQL 似乎有效
【发布时间】:2018-01-09 16:46:35
【问题描述】:

我正在使用一些自定义 DQL 函数来按 PostgreSQL 中的一些 JSONB 字段过滤行。这是我的查询函数:

private function findTopLevelResources(): array {
    return $this->createQueryBuilder('r')
        ->where("JSON_EXISTS(r.contents, '-1') = FALSE")
        ->getQuery()
        ->getResult();
}

运行此代码会导致DriverException 来自AbstractPostgreSQLDriver

An exception occurred while executing 'SELECT r0_.id AS id_0, r0_.marking AS marking_1, r0_.contents AS contents_2, r0_.kind_id AS kind_id_3 FROM resource r0_ WHERE r0_.contents?'-1' = false':

SQLSTATE[3F000]: Invalid schema name: 7 ERROR: schema "r0_" does not exist
LINE 1: ... r0_.kind_id AS kind_id_3 FROM resource r0_ WHERE r0_.conten...
                                                             ^

我尝试从 PHPStorm 手动执行原始 SQL 查询,它工作正常,没有错误。

如何让它在 Doctrine 中工作?

为什么这个查询不适用于 Doctrine,但是当我手动测试它时呢?


这里是JSON_EXISTS:(基于syslogic/doctrine-json-functions

class JsonExists extends FunctionNode
{
    const FUNCTION_NAME = 'JSON_EXISTS';
    const OPERATOR = '?';

    public $jsonData;
    public $jsonPath;

    public function getSql(SqlWalker $sqlWalker)
    {
        $jsonData = $sqlWalker->walkStringPrimary($this->jsonData);
        $jsonPath = $this->jsonPath->value;
        return $jsonData . self::OPERATOR . "'$jsonPath'";
    }

    public function parse(Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->jsonData = $parser->StringPrimary();

        $parser->match(Lexer::T_COMMA);

        $this->jsonPath = $parser->StringPrimary();

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }
}

通过 Symfony 的 YAML 配置注册,如下所示:

doctrine:
  orm:
    dql:
      numeric_functions:
        json_exists: Syslogic\DoctrineJsonFunctions\Query\AST\Functions\Postgresql\JsonExists

东西的版本:

  • PHP 7.1.1
  • doctrine/dbal v2.6.1
  • doctrine/orm dev-master e3ecec3 (== 2.6.x-dev)
  • symfony/symfony v3.3.4

【问题讨论】:

    标签: doctrine-orm dql postgresql-9.5 doctrine-query


    【解决方案1】:

    错误信息是错误线索。

    实际问题是由 PDO 引起的(这就是它在 PHPStorm 中起作用的原因)。当它看到这样的查询时:

    SELECT * FROM foo WHERE contents?'bar'
    

    它将它视为参数化查询,并将问号? 视为参数。由于某种原因,它有时会导致无意义的错误消息。这种特殊情况可以通过在问号后添加一个空格来解决,但对于中间不能有空格的运算符?|?& 不起作用。

    解决方法是使用运算符对应的函数(this question saved the day)。可以使用如下查询来了解它们是如何被调用的:

    SELECT oprname, oprcode FROM pg_operator WHERE oprname IN ('?', '?|', '?&')
    

    这是与 JSON 相关的部分结果:

    • ?jsonb_exists
    • ?|jsonb_exists_any
    • ?&jsonb_exists_all

    因此,可以使用这个等效的查询,而不是通过 PDO 导致问题的先前查询:

    SELECT * FROM foo WHERE jsonb_exists(contents, 'bar')
    

    【讨论】:

      猜你喜欢
      • 2020-02-28
      • 2017-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多