代码之家  ›  专栏  ›  技术社区  ›  jmkjaer

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

  •  0
  • jmkjaer  · 技术社区  · 6 年前

    我有一个包含三列的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)
    

    但后来我发现了错误

    编程错误:提供的绑定数量不正确。当前语句使用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)
    

    但我得到了一个错误:

    操作错误:子选择返回1列-预期为2列

    我不能像在链接答案中那样手动插入值,因为我不知道列表参数包含什么。这意味着我需要做一些 ",".join() 基于列表的长度,但一旦我知道如何使用固定长度的列表进行替换,我就会明白这一点。

    我该怎么做?

    0 回复  |  直到 6 年前
        1
  •  6
  •   David דודו Markovitz    6 年前

    使用 str.join 方法确实是实现这一点的好方法,因为SQL引擎中缺乏对基于容器的占位符的本机支持:

    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 (?,?),(?,?),(?,?),(?,?),(?,?))
    
        2
  •  1
  •   David דודו Markovitz    6 年前

    @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)
    
        3
  •  1
  •   LTheriault    6 年前

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

    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)