我如何 SELECT 在 Python sqlite3 中使用元组的值在哪里?
How do I SELECT WHERE IN VALUES with tuples in Python sqlite3?
我有一个包含三列的 SQLite 数据库,我正在尝试对 SELECT
行的元组使用参数替换。这是我的 table:
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: Incorrect number of bindings supplied. The current statement uses 10, and there are 5 supplied.
显然这意味着我每个元组只需要一个问号,对吧?:
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: sub-select returns 1 columns - expected 2
我无法像链接的答案那样手动插入值,因为我不知道列表参数包含什么。这意味着我需要根据列表的长度执行某种 ",".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)
我有一个包含三列的 SQLite 数据库,我正在尝试对 SELECT
行的元组使用参数替换。这是我的 table:
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: Incorrect number of bindings supplied. The current statement uses 10, and there are 5 supplied.
显然这意味着我每个元组只需要一个问号,对吧?:
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: sub-select returns 1 columns - expected 2
我无法像链接的答案那样手动插入值,因为我不知道列表参数包含什么。这意味着我需要根据列表的长度执行某种 ",".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)