SelectResults:使用查询

概述

SelectResults 从 SQLObject 类上的 .select.selectBy 方法以及 SQLObject 实例上的 SQLMultipleJoinSQLRelatedJoin 访问器返回。

SelectResults 是惰性求值的生成器。仅在您迭代 SelectResults 时才会执行 SQL,一次获取一行。这样,您就可以迭代大型结果,而无需将整个结果集保存在内存中。您还可以执行诸如 .reversed() 之类操作,而无需获取和反转整个结果 - 相反,SQLObject 可以更改发送的 SQL,以便您获得等效的结果。

注意

要一次检索所有结果,请使用 Python 惯用法,即对生成器调用 list() 以强制执行并将结果转换为存储的列表。

您还可以对 SelectResults 进行切片。这会修改 SQL 查询,因此 peeps[:10] 将导致在 SQL 查询的末尾添加 LIMIT 10。如果无法在 SQL 中执行切片(例如,peeps[:-10]),则会执行 select,并在结果列表上执行切片。通常,只有在使用负索引时才会发生这种情况。

在某些情况下,您可能会在 SelectResults 实例中多次获得一个对象,例如,在某些联接中。如果您不希望这样,您可以添加关键字参数 MyClass.select(..., distinct=True),这将导致 SELECT DISTINCT 调用。

您可以通过对结果对象调用 count 来获取结果的长度,而不获取所有结果,例如 MyClass.select().count()。使用 COUNT(*) 查询 - 不会从数据库中获取实际对象。结合切片,这使得批量查询易于编写

start = 20
size = 10
query = Table.select()
results = query[start:start+size]
total = query.count()
print "Showing page %i of %i" % (start/size + 1, total/size + 1)

注意

考虑这种批处理的效率时,有几个因素,并且在很大程度上取决于批处理的使用方式。考虑一个 Web 应用程序,其中您平均显示 100 个结果,一次显示 10 个,并且结果按添加到数据库的日期排序。虽然切片将阻止数据库返回所有结果(从而节省一些通信时间),但数据库仍必须扫描整个结果集以对项目进行排序(因此它知道前十个项目是什么),并且根据您的查询可能需要扫描整个表(取决于您对索引的使用)。索引可能是提高此类情况中重要性的最重要方法,并且您可能会发现缓存比切片更有效。

在这种情况下,缓存意味着检索完整结果。您可以使用 list(MyClass.select(...)) 来执行此操作。当用户逐页查看结果页面时,您可以将这些结果保存一段时间。这意味着搜索结果中的第一页将稍微昂贵一些,但所有后续页面都将非常便宜。

检索方法

迭代

如概述中所述,访问结果的典型方式是将其视为生成器并在其上进行迭代(在循环中,通过转换为列表等)。

getOne(default=optional)

在您的限制导致结果集中始终存在单个记录的情况下,此方法将返回该记录或引发异常:如果找到多个结果,则引发 SQLObjectIntegrityError;如果实际上没有结果,则引发 SQLObjectNotFound,除非您传入默认值,如 .getOne(None)

克隆方法

这些方法返回对其调用的 SelectResults 实例的修改副本,因此可以链接连续调用,例如 results = MyClass.selectBy(city='Boston').filter(MyClass.q.commute_distance>10).orderBy('vehicle_mileage') 或稍后独立使用。

orderBy(column)

采用字符串列名称(可选地以 ‘-’ 为前缀表示降序)或 SQLBuilder 表达式

limit(num)

仅返回前 num 个结果。相当于 results[:num] 切片。

lazyColumns(v)

仅获取结果的 ID,当访问返回实例的属性时,将检索其余列。

reversed()

逆序。作为使用 SQLBuilder.DESC 或“-”调用 orderBy 的替代方案。

distinct()

在 SQL 中,SELECT DISTINCT,删除重复行。

filter(expression)

添加其他表达式以限制结果集。采用 WHERE 子句中有效的字符串静态 SQL 表达式,或 SQLBuilder 表达式。与任何先前的表达式 ANDed。

聚合方法

这些方法通过执行适当的 SQL 查询返回列值(字符串、数字等),而不是新的 SQLResults 实例(不会检索实际的结果行)。任何采用列的方法也可以采用 SQLBuilder 列实例,例如 MyClass.q.size

count()

通过 SQL SELECT COUNT(...) 查询返回结果集的长度。

sum(column)

结果集中 column 的值之和。

min(column)

结果集中 column 的最小值。

max(column)

结果集中 column 的最大值。

avg(column)

结果集中 column 的平均值。