带有“%%”参数的 Postgres 查询未通过 psycopg2 返回结果

Posted

技术标签:

【中文标题】带有“%%”参数的 Postgres 查询未通过 psycopg2 返回结果【英文标题】:Postgres query with '%%' parameter not returning results via psycopg2 【发布时间】:2020-01-30 01:44:33 【问题描述】:

当我在 DBeaver 之类的查询编辑器中执行以下查询时,它会返回结果,但如果我通过 Python 和 psycopg2 执行相同的查询,它不会返回结果。 '%%' 应该匹配任何标题/位置,所以总会返回一些东西。我只是在没有关键字的类别中测试它,但如果它们存在取决于类别,它也会采用一组关键字。所以数组可以是 ['%%'] 或 ['%boston%', '%cambridge%'] 并且两者都应该工作。

select title, link
from internal.jobs 
where (title ilike any(array['%%'])
or location ilike any(array['%%']))
order by "publishDate" desc
limit 1;

我尝试在字符串的开头添加 E 标志。例如。 E'%%'

Python:

import psycopg2

FILTERS = 
    'AllJobs': [],
    'BostonJobs': ['boston', 'cambridge'],
    'MachineLearningJobs': ['ml', 'machine learning']


conn = psycopg2.connect("dbname=test user=postgres")
cur = conn.cursor()

sql = """
select title, link
from internal.jobs 
where (title ilike any(array[%s])
or location ilike any(array[%s]))
order by "publishDate" desc
limit 1;
"""

for title, tags in FILTERS.items():
    if not tags:
        formatted_filters = "'%%'" # Will match any record
    else:
        formatted_filters = ','.join([f"'%keyword%'" for keyword in tags])

    cur.execute(sql, (formatted_filters))
    results = cur.fetchone()
    print(results)

【问题讨论】:

你使用的 Python 代码是什么? 你有单引号、双引号和百分号,所以我高度怀疑你的问题是一个需要转义但没有看到 Python 代码就无法知道的字符。 Here's more info. 谢谢@AlexW 我怀疑你是对的,有人可能会指出我正确的方向来逃避 % 符号/以这种方式构建数组。 【参考方案1】:

您可以使用cur.mogrify() 查询查看最终生成的 SQL,检查 psql 是否有效,以及您需要如何调整它。

很可能您必须将每个% 加倍。

【讨论】:

【参考方案2】:

感谢 Piro 提供了非常有用的 cur.mogrify() 线索。这有助于我进一步调试查询以找出问题所在。

我最终删除了额外的引号集,我使用了一个命名参数,现在它可以按预期工作了。

更新代码:

import psycopg2

FILTERS = 
    'AllJobs': [],
    'BostonJobs': ['boston', 'cambridge'],
    'MachineLearningJobs': ['ml', 'machine learning']


conn = psycopg2.connect("dbname=test user=postgres")
cur = conn.cursor()

sql = """
select title, link
from internal.jobs 
where (title ilike any(array[%(filter)s])
or location ilike any(array[%(filter)s]))
order by "publishDate" desc
limit 1;
"""

for title, tags in FILTERS.items():
    if not tags:
        formatted_filters = '%%' # Will match any record
    else:
        formatted_filters = [f'%keyword%' for keyword in tags]

    print(cur.mogrify(sql, 'filter': formatted_filters))
    cur.execute(sql, 'filter': formatted_filters)
    results = cur.fetchone()
    print(results)

【讨论】:

以上是关于带有“%%”参数的 Postgres 查询未通过 psycopg2 返回结果的主要内容,如果未能解决你的问题,请参考以下文章

带有 jsonb 参数的 Postgres 函数

使用带有 Spring Data 和绑定参数的 Postgres JSONB 查询失败并出现 InvalidDataAccessApiUsageException

Postgres 中的 LTREE 祖先查询未按预期工作

Django Admin 搜索查询未命中 Postgres 索引

带有 postgres-xl 的 zombodb:“zombodb.so:未定义符号:session_auth_is_superuser”

带有 resultClass 参数的 NamedQuery 未返回查询结果的预期“类型”