如何在Python sqlite3中使用元组选择WHERE值?

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

我有一个包含三列的SQLite数据库,并且我试图对SELECT行的元组使用参数替换。这是我的桌子:

conn = sqlite3.connect("SomeDb.sqlite3")

conn.execute("""
CREATE TABLE RoadSegmentDistribution(
    Source INTEGER,
    Destination INTEGER,
    Distribution TEXT
)
""")

我知道如何用非元组替代,但是我不知道如何用元组替代。

基于this answer,我以为我只需要替换元组列表中的每个值:

for e in conn.execute("""
    SELECT *
    FROM RoadSegmentDistribution
    WHERE (
        Source, Destination
    ) IN (VALUES (?,?), (?,?), (?,?), (?,?), (?,?))
    """,
    [(1, 2),(2, 3),(4, 5),(6, 7),(8, 9)]
):
    print(e)

但随后我得到了错误

ProgrammingError:提供的绑定数量不正确。当前语句使用10,并且提供了5。

显然,这意味着每个元组只需要一个问号,对吧?:

for e in conn.execute("""
    SELECT *
    FROM RoadSegmentDistribution
    WHERE (
        Source, Destination
    ) IN (VALUES (?), (?), (?), (?), (?))
    """,
    [(1, 2),(2, 3),(4, 5),(6, 7),(8, 9)]
):
    print(e)

但随后出现此错误:

[OperationalError:子选择返回1列-预期2

我无法像链接的答案一样手动插入值,因为我不知道list参数包含什么。这意味着我需要根据列表的长度执行某种",".join(),但是一旦我知道如何用固定长度的列表进行替换,我就会明白这一点。

我将如何做?

python sql python-3.x sqlite substitution
1个回答
0
投票

考虑到在SQL引擎中缺乏对基于容器的占位符的本地支持,使用str.join方法确实是实现此目的的好方法:

values = [(1, 2), (2, 3), (4, 5), (6, 7), (8, 9)]

for e in conn.execute(f"""
    SELECT *
    FROM RoadSegmentDistribution
    WHERE (
        Source, Destination
    ) IN (VALUES {','.join(f'({",".join("?" * len(t))})' for t in values)})
    """,
    [i for t in values for i in t]
):
    print(e)

其中,以给定的values

f"""
    SELECT *
    FROM RoadSegmentDistribution
    WHERE (
        Source, Destination
    ) IN (VALUES {','.join(f'({",".join("?" * len(t))})' for t in values)})
"""

将扩展为:

SELECT *
FROM RoadSegmentDistribution
WHERE (
    Source, Destination
) IN (VALUES (?,?),(?,?),(?,?),(?,?),(?,?))

0
投票

您可以尝试以不同的方式构造查询并根据您传递的参数生成查询。

query_head ="SELECT * FROM RoadSegmentDistribution WHERE "
params = [(1, 2),(2, 3),(4, 5),(6, 7),(8, 9)]

def add_condition(pair):
    condition = f"(Source = {pair[0]} AND Destination = {pair[1]})"
    return condition

def build_query(query_head,params):
    conditions = ' OR '.join([add_condition(param) for param in params])
    query = query_head+conditions
    return query

query = build_query(query_head,params)
conn.
© www.soinside.com 2019 - 2024. All rights reserved.