使用 pg8000 在 sql 脚本中使用位置参数的问题
Issue using positional parameters in sql script, using pg8000
我有以下 SQL 查询:
query_string = "SELECT sum(unmatched), " \
"TIMESTAMP WITH TIME ZONE 'epoch' + INTERVAL '1 second' * " \
"round(extract('epoch' from time_window) / {}) * {} as time_window " \
"FROM aggregate_counts WHERE reconciliation_name = %s " \
"GROUP BY round(extract('epoch' from time_window) / {})".format(interval_sec, interval_sec, interval_sec)
cur.execute(query_string, (reconciliation_name))
它工作正常,除非我想避免对 "interval_sec" 使用字符串替换,而是使用位置参数,就像我对其他参数所做的那样。问题是,如果我这样做:
query_string = "SELECT sum(unmatched), " \
"TIMESTAMP WITH TIME ZONE 'epoch' + INTERVAL '1 second' * " \
"round(extract('epoch' from time_window) / %s) * %s as time_window " \
"FROM aggregate_counts WHERE reconciliation_name = %s " \
"GROUP BY round(extract('epoch' from time_window) / %s)"
cur.execute(query_string, (interval_sec, interval_sec, reconciliation_name, interval_sec))
我收到以下错误:
Error handler middleware caught the following exception: {'S':
'ERROR', 'V': 'ERROR', 'C': '42803', 'M': 'column
"aggregate_counts.time_window" must appear in the GROUP BY clause or
be used in an aggregate function', 'P': '177', 'F': 'parse_agg.c',
'L': '1344', 'R': 'check_ungrouped_columns_walker'}
File
File "pg8000/core.py", line 1829, in execute
ps = cache['ps'][key]
KeyError: ("SELECT sum(unmatched), TIMESTAMP WITH TIME ZONE 'epoch' + INTERVAL '1 second' * round(extract('epoch' from time_window) / %s) * %s as time_window FROM aggregate_counts WHERE reconciliation_name = %s GROUP BY round(extract('epoch' from time_window) / %s)", ((701, 1, ), (701, 1, ), (705, 0, .text_out at 0x10c58cea0>)))
位置参数只能用于比较(=、>=、< 等...)吗?
所以基本不可能有这个。原因是 select 子句中的 %s 将被转换为比方说 $x 位置参数,而 group by 中的 %s 将被转换为 $y(x 和 y 是各自的位置)。现在 postgres 有没办法知道解决后,这两个会是一样的。因此它假定 "aggregate_counts.time_window" 不存在于 GROUP BY 中。我知道这不是完美的解释,但这就是正在发生的事情。
我有以下 SQL 查询:
query_string = "SELECT sum(unmatched), " \
"TIMESTAMP WITH TIME ZONE 'epoch' + INTERVAL '1 second' * " \
"round(extract('epoch' from time_window) / {}) * {} as time_window " \
"FROM aggregate_counts WHERE reconciliation_name = %s " \
"GROUP BY round(extract('epoch' from time_window) / {})".format(interval_sec, interval_sec, interval_sec)
cur.execute(query_string, (reconciliation_name))
它工作正常,除非我想避免对 "interval_sec" 使用字符串替换,而是使用位置参数,就像我对其他参数所做的那样。问题是,如果我这样做:
query_string = "SELECT sum(unmatched), " \
"TIMESTAMP WITH TIME ZONE 'epoch' + INTERVAL '1 second' * " \
"round(extract('epoch' from time_window) / %s) * %s as time_window " \
"FROM aggregate_counts WHERE reconciliation_name = %s " \
"GROUP BY round(extract('epoch' from time_window) / %s)"
cur.execute(query_string, (interval_sec, interval_sec, reconciliation_name, interval_sec))
我收到以下错误:
Error handler middleware caught the following exception: {'S': 'ERROR', 'V': 'ERROR', 'C': '42803', 'M': 'column "aggregate_counts.time_window" must appear in the GROUP BY clause or be used in an aggregate function', 'P': '177', 'F': 'parse_agg.c', 'L': '1344', 'R': 'check_ungrouped_columns_walker'}
File File "pg8000/core.py", line 1829, in execute ps = cache['ps'][key] KeyError: ("SELECT sum(unmatched), TIMESTAMP WITH TIME ZONE 'epoch' + INTERVAL '1 second' * round(extract('epoch' from time_window) / %s) * %s as time_window FROM aggregate_counts WHERE reconciliation_name = %s GROUP BY round(extract('epoch' from time_window) / %s)", ((701, 1, ), (701, 1, ), (705, 0, .text_out at 0x10c58cea0>)))
位置参数只能用于比较(=、>=、< 等...)吗?
所以基本不可能有这个。原因是 select 子句中的 %s 将被转换为比方说 $x 位置参数,而 group by 中的 %s 将被转换为 $y(x 和 y 是各自的位置)。现在 postgres 有没办法知道解决后,这两个会是一样的。因此它假定 "aggregate_counts.time_window" 不存在于 GROUP BY 中。我知道这不是完美的解释,但这就是正在发生的事情。