使用 python sqlite3 — 从 sqlite 表中选择列表中的 rowid数据库API 2.0

发布于 2024-11-03 04:43:35 字数 364 浏览 1 评论 0原文

以下有效:

>>> 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 列表,而不必先将其格式化为字符串?

The following works:

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

The following doesn't:

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

Is there a way to pass in a python list without having to format it into a string first ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

最冷一天 2024-11-10 04:43:35

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

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

cursor.execute(sql, args)

Unfortunately not. Each value must be given its own parameter mark (?).
Since the argument list can (presumably) have arbitrary length, you must use string formating to build the correct number of parameter marks. Happily, that isn't so hard:

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

cursor.execute(sql, args)
凉城 2024-11-10 04:43:35

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

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

In Python 3.6 you can also build queries with the f strings:

args=[2, 3]
query = f"SELECT * FROM sqlitetable WHERE rowid in ({','.join(['?']*len(args))})"
cursor.execute(query, args)
流殇 2024-11-10 04:43:35

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

SQLite natively supports only the types TEXT, INTEGER, REAL, BLOB and NULL. If you want to use other types you must add support for them yourself. The detect_types parameter and the using custom converters registered with the module-level register_converter() function allow you to easily do that.

As described before, SQLite supports only a limited set of types natively.

To use other Python types with SQLite, you must adapt them to one of the sqlite3 module’s supported types for SQLite: one of NoneType, int, float, str, bytes.

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

最佳男配角 2024-11-10 04:43:35

我需要在查询中包含多个 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())

I needed to include more than one IN clause with a query along with other named parameters and came up with a helper method that would let me do:

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)

Which uses this helper method:

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())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文