免责声明,我非常清楚有更好的方式来表达问题,如果有人想提出更好的方式,我很乐意改变它
过去 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)
显然,这是行不通的。简而言之,我希望它只查询存在数据的列。完成此任务的最有效方法是什么?
这演示了动态构建查询:
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;