我拼命想在Symfony2中包含LEVENSHTEIN函数,但我仍然收到错误。Specs+到目前为止我所做的:
- PostgreSQL 9.3
- 包含在fuzzystrmatch扩展中的LEVENSHTEIN
-
通过shell执行测试了该函数。效果非常好:
postgres=# SELECT levenshtein('test', 'text'); levenshtein ------------- 1 (1 row)
-
增加了DQL:中的功能
<?php namespace AppBundle'DQL; use Doctrine'ORM'Query'AST'Functions'FunctionNode; use Doctrine'ORM'Query'Lexer; use Doctrine'ORM'Query'Parser; use Doctrine'ORM'Query'SqlWalker; class LevenshteinFunction extends FunctionNode { public $firstStringExpression = null; public $secondStringExpression = null; public function getSql(SqlWalker $sqlWalker) { return 'LEVENSHTEIN(' . $this->firstStringExpression->dispatch($sqlWalker) . ', ' . $this->secondStringExpression->dispatch($sqlWalker) . ')'; } public function parse(Parser $parser) { // levenshtein(str1, str2) $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); $this->firstStringExpression = $parser->StringPrimary(); $parser->match(Lexer::T_COMMA); $this->secondStringExpression = $parser->StringPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } }
配置yml
orm: auto_generate_proxy_classes: "%kernel.debug%" auto_mapping: true dql: numeric_functions: LEVENSHTEIN: AppBundle'DQL'LevenshteinFunction
-
问题:在我的存储库中执行以下代码块时,会出现以下错误:
$this->getEntityManager()->createQuery("SELECT LEVENSHTEIN('test', 'text') FROM AppBundle:User"); return $query->getResult();
SQLSTATE[44283]:未定义的函数:7错误:函数levenstein(未知,未知)不存在
我错过了什么?为什么DQL/Symfony/PDO/。。。识别功能?非常感谢您的帮助!
错误来自Postgres,似乎是可见性问题。
当然,必须安装附加模块fuzzystrmatch
。您显然做到了,否则您的函数调用在psql中也无法工作。
- 如何在导出中排除PL/pgSQL函数
如果它在psql中有效,但在你的应用程序中无效,那么只剩下一些可能的解释了。显而易见的第一个:
-
您是否连接到同一数据库?(相同的服务器,相同的端口,相同的数据库?)
-
您正在与同一用户连接?可能而不是。。。
-
如果与其他用户连接(但无论如何),请检查您是否使用相同的搜索路径。在任一连接中运行并比较:
SHOW search_path;
详细信息-以及如何设置
search_path
:- search_ path如何影响标识符解析和"搜索路径";当前模式"
请注意,扩展可以安装到您选择的任何模式。默认值是search_path
中的第一个模式(安装时的"当前模式",通常是public
,但我不知道您的安装。文档:
如果未指定,并且扩展名的控制文件未指定模式,则使用当前默认的对象创建模式。
运行此程序可以诊断以下几件事:
SELECT e.extname AS extension, nsp.nspname AS schema
, r.rolname AS schema_owner, nsp.nspacl AS schema_acl
FROM pg_extension e
JOIN pg_namespace nsp ON nsp.oid = e.extnamespace
JOIN pg_roles r ON r.oid = nsp.nspowner
你会得到这样的东西:
extension | schema | schema_owner | schema_acl ---------------+------------+--------------+------------------------------------- adminpack | pg_catalog | postgres | {postgres=UC/postgres,=U/postgres} plpgsql | pg_catalog | postgres | {postgres=UC/postgres,=U/postgres} fuzzystrmatch | public | postgres | {postgres=UC/postgres,=UC/postgres} tablefunc | public | postgres | {postgres=UC/postgres,=UC/postgres} ...
如果schema_acl
包括=U/postgres
(U
表示USAGE
),则public
角色具有访问权限,即每个人。
相应地为您的连接设置search_path
,或者(重新)安装到一个可见的模式,它应该可以工作。
理论上,拥有角色或超级用户可能已经从函数本身吊销了EXECUTE
权限。。。
您的函数类在我看来还可以,但您的配置可能是错误的。这就是我的CAST
功能:
doctrine:
orm:
dql:
string_functions:
CAST: App'MyBundle'Doctrine'DBAL'Functions'Porgres'Cast
您应该注意,对于不同类型的函数,即string_functions
、numeric_functions
、datetime_functions
,您有不同的集合。所有这些都列在官方文件中。
除此之外,清理缓存后,代码应该可以正常工作。