如何从列表中填充CTE值?

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

在下面的示例中,我想使用标准的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-3.x sqlite python-3.5 common-table-expression
1个回答
0
投票

我实际上不知道您是否可以通过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)
© www.soinside.com 2019 - 2024. All rights reserved.