以下作品:
>>> 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 列表而不必先将其格式化为字符串?
不幸的是没有。每个值都必须有自己的参数标记 (
?
)。
由于参数列表(大概)可以具有任意长度,因此您必须使用字符串格式来构建正确数量的参数标记。幸运的是,这并不难:
args=[2,3]
sql="select * from sqlitetable where rowid in ({seq})".format(
seq=','.join(['?']*len(args)))
cursor.execute(sql, args)
在 Python 3.6 中,您还可以使用 f 字符串构建查询:
args=[2, 3]
query = f"SELECT * FROM sqlitetable WHERE rowid in ({','.join(['?']*len(args))})"
cursor.execute(query, args)
SQLite 本身仅支持 TEXT、INTEGER、REAL、BLOB 和 NULL 类型。如果您想使用其他类型,您必须自己添加对它们的支持。 detector_types 参数和使用模块级 register_converter() 函数注册的自定义转换器可以让您轻松做到这一点。
如前所述,SQLite 仅原生支持有限的类型。
要将其他 Python 类型与 SQLite 一起使用,您必须将它们调整为 sqlite3 模块支持的 SQLite 类型之一:NoneType、int、float、str、bytes 之一。
我需要在查询中包含多个
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())
查看here,了解使用 sqlite3 和 python 将列表作为输入的不同方法的说明。