如何正确理解“游标”

3 投票
1 回答
1026 浏览
提问于 2025-04-16 20:43

我正在尝试在我的应用中使用游标,但文档对我来说不够清晰。

谷歌对游标的描述是:http://code.google.com/appengine/docs/python/datastore/queries.html#Query_Cursors

游标的位置是指在结果列表中最后一个返回结果之后的位置。游标并不是列表中的相对位置(它不是一个偏移量);而是一个标记,数据存储可以在开始索引扫描结果时跳转到这个标记。如果在使用游标之间,查询的结果发生了变化,查询只会注意到游标之后结果的变化。如果在游标的位置之前出现了新的结果,那么在获取游标之后的结果时,这个新结果不会被返回。同样地,如果某个实体不再是查询的结果,但在游标之前出现过,那么游标之后的结果也不会改变。如果最后返回的结果从结果集中被移除,游标仍然知道如何找到下一个结果。

根据我的理解,查询结果总是会以默认的顺序返回(比如按 __ key __ 排序)。然后,使用指定的游标,它会添加一个过滤器,过滤掉这个游标之前的所有结果。就像谷歌之前提到的那样。这是真的吗?

关于使用 __ key __ 和非唯一属性进行分页的内容:http://code.google.com/appengine/articles/paging.html

还有一个问题,游标可以与迭代或任务一起使用吗?出于某些原因,这个功能无法正常工作。通常在迭代过程中可能会生成“查询未找到”的错误。

这是我的示例:

people = Person.all().filter("age > ", 30)
if cursor:
     people.with_cursor(cursor)

try:
     for person in people: # query not found
        cursor = people.cursor()

except DeadlineExceededError:
     taskqueue.add(url="/people", params= {"cursor", cursor})

1 个回答

3

你的理解基本上是对的,但光把游标当作简单的过滤条件是不够的。假设你有一组结果,首先按年龄排序,然后按名字排序。如果你最后得到的结果是年龄30,名字是Bob,那么没有任何条件能精确返回Bob之后的结果——比如说,条件是年龄大于等于30,名字大于Bob,这样就不会返回31岁的Alice。

游标更像是你在结果集中的一个书签。它标记了你停下来的地方,这样你可以稍后再回来。如果在你使用游标之前或之后,结果集发生了变化,游标仍然停留在原来的位置——所以你总是能从你停下的地方继续。

至于你其他的问题:是的,查询总是有一个隐含的顺序。这个顺序取决于具体的查询(在你的例子中,首先按年龄,然后按关键字),但它确保了结果的总顺序。你提到的分页文章已经过时了,它提供了一种过时的分页方法。你可以忽略它,直接使用游标。

你可以在任务之间(以及用户之间)很好地传递游标。如果你遇到错误,你需要给我们看一下错误堆栈信息,这样我们才能帮到你。

撰写回答