如何省略 SQL 查询的某些部分

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

免责声明,我非常清楚有更好的方式来表达问题,如果有人想提出更好的方式,我很乐意改变它

过去 4 年我一直在使用 DynamoDB,现在我正在将我的一个表切换到 postgreSQL。我一直在使用 psycopg2 python 库来测试一些查询。用户将需要对数据库进行过滤,因此最好有一个多合一的过滤器查询。

我希望用户能够为给定的过滤器选择多个值或不选择任何值,如果没有,则不应过滤该字段。这是一个基本查询的样子(这只是一个可以完成我的问题的例子)。

conn = psycopg2.connect(host=ENDPOINT, port=PORT, database=DBNAME, user=USER, password=PASSWORD, sslrootcert="SSLCERTIFICATE")
cur = conn.cursor()
sql = """
    SELECT * FROM table_name 
    WHERE column_1 in %s AND column_2 in %s
    ORDER BY datetime DESC
"""
sql_values = (("XXXXYXY", "XXXYYXXY"), ("ZGZGZGZGGG","GZGGGGZGG"))
cur.execute(sql, sql_values)

这是一种查询,其中 column_2 没有值:

conn = psycopg2.connect(host=ENDPOINT, port=PORT, database=DBNAME, user=USER, password=PASSWORD, sslrootcert="SSLCERTIFICATE")
cur = conn.cursor()
sql = """
    SELECT * FROM table_name 
    WHERE column_1 in %s AND column_2 in %s
    ORDER BY datetime DESC
"""
sql_values = (("XXXXYXY", "XXXYYXXY"), ())
cur.execute(sql, sql_values)

显然,这是行不通的。简而言之,我希望它只查询存在数据的列。完成此任务的最有效方法是什么?

python sql postgresql psycopg2
1个回答
1
投票

这演示了动态构建查询:

conn = psycopg2.connect(host=ENDPOINT, port=PORT, database=DBNAME, user=USER, password=PASSWORD, sslrootcert="SSLCERTIFICATE")
cur = conn.cursor()

where = []
data = []

for q,r in (
    ("column_1", ("XXXXYXY","XXXYYXXY")),
    ("column_2", ("XXXZZXY","XXZZYXXY")),
    ("column_3", ())
    ):
    if r:
        where.append( "%s in %%s" % q )
        data.append(r)

sql = "SELECT * FROM table_name WHERE "
sql += " AND ".join(where)
sql += " ORDER BY datetime DESC;";
print(sql)
cur.execute(sql, data)

输出:

SELECT * FROM table_name WHERE column_1 in %s AND column_2 in %s ORDER BY datetime DESC;
© www.soinside.com 2019 - 2024. All rights reserved.