使用 python sqlite3 从 sqlite 表中选择列表中的 rowid — DB-API 2.0

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

以下作品:

>>> cursor.execute("select * from sqlitetable where rowid in (2,3);")

以下情况则不然:

>>> cursor.execute("select * from sqlitetable where rowid in (?) ", [[2,3]] )
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.

有没有办法传入 python 列表而不必先将其格式化为字符串?

python sqlite
5个回答
63
投票

不幸的是没有。每个值都必须有自己的参数标记 (

?
)。 由于参数列表(大概)可以具有任意长度,因此您必须使用字符串格式来构建正确数量的参数标记。幸运的是,这并不难:

args=[2,3]
sql="select * from sqlitetable where rowid in ({seq})".format(
    seq=','.join(['?']*len(args)))

cursor.execute(sql, args)

15
投票

在 Python 3.6 中,您还可以使用 f 字符串构建查询:

args=[2, 3]
query = f"SELECT * FROM sqlitetable WHERE rowid in ({','.join(['?']*len(args))})"
cursor.execute(query, args)

0
投票

SQLite 本身仅支持 TEXT、INTEGER、REAL、BLOB 和 NULL 类型。如果您想使用其他类型,您必须自己添加对它们的支持。 detector_types 参数和使用模块级 register_converter() 函数注册的自定义转换器可以让您轻松做到这一点。

如前所述,SQLite 仅原生支持有限的类型。

要将其他 Python 类型与 SQLite 一起使用,您必须将它们调整为 sqlite3 模块支持的 SQLite 类型之一:NoneType、int、float、str、bytes 之一。

https://docs.python.org/3.6/library/sqlite3.html#using-adapters-to-store-additional-python-types-in-sqlite-databases


0
投票

我需要在查询中包含多个

IN
子句以及其他命名参数,并想出了一种可以让我这样做的辅助方法:

params = {'mn': 5, 'mx': 15}
in_a = sql_in([1,2,3], params, prefix='a')
in_b = sql_in([5,6,7], params, prefix='b')
query = (
    "SELECT rowid, name FROM tbl "
    "WHERE value BETWEEN :mn AND :mx"
    f" AND (alpha IN {in_a} OR beta IN {in_b})"
)
dbcon.execute(query, params)

其中使用了这个辅助方法:

def sql_in(values, params, *, prefix='in'):
    """Generate an IN clause for SQLite using named placeholders.
    Given values=[1,2,3], will return:
        '(:in0,:in1,:in2)'
    after doing:
        params.update({'in0':1,'in1':2,'in2':3})
    If you're using this multiple times with a single dbcon.execute(),
    you need to give each one a distinct prefix, e.g.:
      params = {}
      in_a = sql_in([1,2,3], params, prefix='a')
      in_b = sql_in([5,6,7], params, prefix='b')
      dbcon.execute(f'SELECT * FROM tbl WHERE a IN {in_a} OR b IN {in_b}', params)
    """
    def inner():
        yield '('
        delim = ':'
        for i, val in enumerate(values):
            key = f'{prefix}{i}'
            assert key not in params
            params[key] = val
            yield delim
            yield key
            delim = ',:'
        yield ')'
    return ''.join(inner())

0
投票

查看here,了解使用 sqlite3 和 python 将列表作为输入的不同方法的说明。

© www.soinside.com 2019 - 2024. All rights reserved.