在select查询中解决SQLite参数限制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在select查询中解决SQLite参数限制相关的知识,希望对你有一定的参考价值。

我有一个GUI应用程序,其中包含人员列表,其中包含人员的数据库ID及其属性。像这样的东西:

+----+------+
| ID | Name |
+----+------+
|  1 | John |
|  2 | Fred |
|  3 | Mary |
[...]

此列表可以过滤,因此人们的数量和类型会不时地依赖。要获取Peewee Person对象的列表,我首先获取可见ID列表并使用以下查询:

ids = [row[0] for row in store]
Person.select().where(Person.id.in_(ids))

这反过来转换为以下SQL:

('SELECT "t1"."id", "t1"."name" FROM "person" AS "t1" WHERE ("t1"."id" IN (?, ?, ?, ...))', [1, 2, 3, ...])

这会在超过1000人的Windows上引发OperationalError: too many SQL variables错误。这在Peewee和SQLite文档中有记录。在线提供的变通方法通常涉及批量插入以及以块的形式分割动作的方法。有没有办法解决这个限制与提到的SELECT ... WHERE ... IN查询?

在列表推导中获取单独的对象太慢了:

people = [Person.get_by_id(row[0]) for row in store]

也许拆分最多1000个项目中的ID列表,在每个块上使用select查询然后以某种方式组合它们?

答案

身份证来自何处?当然,最好的答案是避免使用那么多参数。例如,如果您的ID列表可以表示为某种类型的查询,那么您只需编写一个子查询,例如

my_friends = (Relationship
              .select(Relationship.to_user)
              .where(Relationship.from_user == me))
tweets_by_friends = Tweet.select().where(Tweet.user.in_(my_friends))

在上面,我们可以从第一个查询中获取所有用户ID,并将它们作为列表集中传递到第二个查询中。但由于第一个查询(“我所有的朋友”)本身就是一个查询,我们可以组成它们。您也可以使用JOIN而不是子查询,但希望您明白这一点。

如果这是不可能的,并且您认真拥有> 1000个ID的列表......这样的列表在GUI应用程序中有用吗?超过1000个东西是很多东西。

试着回答你提出的问题 - 你必须把它们搞得一团糟。哪个好。只是:

user_ids = list_of_user_ids
accum = []
# 100 at a time.
for i in range(0, user_ids, 100):
    query = User.select().where(User.id.in_(user_ids[i:i+100]))
    accum.extend([user for user in query])
return accum

但严重的是,我认为你实现这一点的方式存在问题,甚至需要过滤掉这么多的ID。

以上是关于在select查询中解决SQLite参数限制的主要内容,如果未能解决你的问题,请参考以下文章

android如何用SQLite 的query方法查询某行某列的值,也就是两个限制条件,请问参数怎么写?

在python中使用sqlite3注入安全参数化查询[重复]

Sqlite 参数化 模糊查询 解决方案

SQLite查询系统参数

你可以使用 POST 在 Solr (/select) 中运行查询吗

增强 select sqlite 查询的性能