在下面的示例中,我想使用标准的Python SQLite3 API从列表中动态填充查询中CTE的值:
-- test schema
CREATE TABLE t AS SELECT "" AS k FROM (VALUES (1),(3));
-- query to build
WITH cte(k) AS (VALUES
(1),
(2),
(3)
) SELECT * FROM t INNER JOIN cte USING(k);
这不起作用:
import sqlite3
SQL_INIT="""
CREATE TABLE t AS SELECT "" AS k FROM (VALUES (1),(3));
"""
SQL_QUERY="""
WITH cte(k) AS (VALUES
(:values)
) SELECT * FROM t INNER JOIN cte USING(k);
"""
conn = sqlite3.connect(':memory:')
conn.executescript(SQL_INIT)
params = dict(
values=(1,2,3)
)
for row in conn.execute(SQL_QUERY, params):
print(row)
所以有一种方法可以使用占位符从Python代码填充CTE值?如果没有,什么是一个好的解决方法?我真的必须求助于纯字符串操作和手动值清除吗?
为了简单起见,上面的示例使用整数值填充CTE。但是该解决方案应该适用于数字和字符串。
我实际上不知道您是否可以通过Python API以这种方式使用CTE语法。假设您can,那么您面临的问题是您试图将集合绑定到查询中的单个占位符。相反,您可以尝试将集合绑定到具有正确数量?
占位符的预准备语句。
vals = (1, 2, 3)
vals_clause = '(?)' + ',(?)'*(len(vals)-1)
sql = 'WITH cte(k) AS (VALUES ' + vals_clause + ')'
sql = sql + 'SELECT * FROM t INNER JOIN cte USING(k)'
for row in conn.execute(SQL_QUERY, vals):
print(row)