繁体   English   中英

如何在 Python sqlite3 中使用元组选择值中的位置?

[英]How do I SELECT WHERE IN VALUES with tuples in Python sqlite3?

我有一个包含三列的 SQLite 数据库,我正在尝试使用元组的参数替换来SELECT行。 这是我的表:

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

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

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

基于这个答案,我想我只需要替换元组列表中的每个值:

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() ,但是一旦我知道如何使用固定长度的列表进行替换,我就会弄清楚这一点。

我该怎么做?

鉴于 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 (?,?),(?,?),(?,?),(?,?),(?,?))

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

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.execute(query)

@jmkjaer:不是答案,但需要澄清

你反其道而行之——
您的查询需要 10 个绑定,它并不关心它们如何在查询中分布。
您需要做的就是提供一个包含 10 个元素的列表:

[1,2, 2,3, 4,5, 6,7, 8,9]

演示

import sqlite3

conn = sqlite3.connect(':memory:')
vals = [(1, 2),(2, 3),(4, 5),(6, 7),(8, 9)]
flat_vals = [e for t in vals for e in t ]

for e in conn.execute("values (?,?),(?,?),(?,?),(?,?),(?,?)",flat_vals):
    print(e)


(1, 2)
(2, 3)
(4, 5)
(6, 7)
(8, 9)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM