SQLite3 Python:执行许多选择
Posted
技术标签:
【中文标题】SQLite3 Python:执行许多选择【英文标题】:SQLite3 Python: executemany SELECT 【发布时间】:2012-12-18 00:43:53 【问题描述】:我正在尝试使用 executemany 函数从具有一些 WHERE 约束的一行中取出表中的所有行
import sqlite3
con = sqlite3.connect('test.db')
cur = con.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS Genre (id INTEGER PRIMARY KEY, genre TEXT NOT NULL)')
values = [
(None, 'action'),
(None, 'adventure'),
(None, 'comedy'),
]
cur.executemany('INSERT INTO Genre VALUES(?, ?)', values)
ids=[1,2]
cur.executemany('SELECT * FROM Genre WHERE id=?', ids)
rows = cur.fetchall()
print rows
错误
cur.executemany('SELECT * FROM Genre WHERE id=?', ids)
sqlite3.ProgrammingError: You cannot execute SELECT statements in executemany()
【问题讨论】:
【参考方案1】:使用execute()
执行返回数据的查询。
您要么必须使用循环,要么使用 IN (id1, id2, id3)
where 子句:
cur.execute('SELECT * FROM Genre WHERE id in (0)'.format(', '.join('?' for _ in ids)), ids)
上述表达式为ids
中的每个项目插入一个单独的?
占位符(用逗号分隔)。
【讨论】:
谢谢Martijin,我不知道IN子句它有很大帮助。 cursor.executemany方法是不是重复调用cursor.execute实现的? @shadow0359: 不,cursor.execute()
实际上是通过将参数放入列表然后执行cursor.executemany()
来实现的。请参阅_pysqlite_query_execute
function(execute()
和 executemany()
之间的唯一区别是后者将 multiple
设置为 1)。
@MasonSchmidgall 它确实不会创建注入漏洞。它专门生成防止 SQL 注入的SQL 参数。例如。 ids = (42, "Robert'; DROP TABLE Students; --",)
生成查询字符串 SELECT * FROM Genre WHERE id in (?, ?)
,使用 2 个 SQL 参数执行,数据库安全地引用这些参数作为值。 ids[1]
绝不会作为 SQL 命令执行。
@MasonSchmidgall 请仔细阅读此处插入的确切文本。如果要将ids
变量的内容 插入到查询字符串中,那么是的,会有一个漏洞,但是这不是这段代码的作用。我们只是使用序列的length 在这里生成多个?
参数占位符并将那些 放入查询中。 ids
值本身不会被此代码插值,而是作为参数值传递给数据库。【参考方案2】:
你收到的错误信息很简单,You cannot execute SELECT statements in executemany()
只需更改您的executemany
即可执行:
ids=[1,2]
for id in ids:
cur.execute('SELECT * FROM Genre WHERE id=?', id)
rows = cur.fetchall()
print rows
【讨论】:
这也有帮助,但 Martijin 对我的情况更好,不过感谢您的帮助。 这是否涉及为每个 id 重新解析查询?还是 python-sqlite3 缓存它们? @rsaxvc 根据the python documentation,“sqlite3 模块内部使用语句缓存来避免 SQL 解析开销。”对我来说,这意味着它不会每次都重新解析查询。以上是关于SQLite3 Python:执行许多选择的主要内容,如果未能解决你的问题,请参考以下文章
在 SQLite3 表中的行上有效地执行 python 代码