在给定NDB游标的情况下,获取结果的上一页的正确方法是什么? [英] What is the correct way to get the previous page of results given an NDB cursor?

查看:102
本文介绍了在给定NDB游标的情况下,获取结果的上一页的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过GAE提供一个API,允许用户通过一组实体向前和向后翻页。我已阅读了有关NDB查询文档页面上的游标的部分,其中包含一些示例代码,该代码描述了如何通过查询结果向后翻页,但似乎没有按照需要工作。我使用的是GAE Development SDK 1.8.8。

下面是该示例的一个修改版本,它创建5个样本实体,获取并打印第一页,前进到打印第二页,然后尝试退后并再次打印第一页:

 从Google导入pprint 
。 appengine.ext import ndb

class Bar(ndb.Model):
foo = ndb.StringProperty()

#ndb.put_multi([Bar(foo = a),Bar(foo =b),Bar(foo =c),Bar(foo =d),Bar(foo =e))]

# 建立。
q = Bar.query()
q_forward = q.order(Bar.foo)
q_reverse = q.order(-Bar.foo)

#第一页。
bars1,cursor1,more1 = q_forward.fetch_page(2)
pprint.pprint(bars1)

#获取下一页(第2页)。
bars2,cursor2,more2 = q_forward.fetch_page(2,start_cursor = cursor1)
pprint.pprint(bars2)

#读取上一页。
rev_cursor2 = cursor2.reversed()
bars3,cursor3,more3 = q_reverse.fetch_page(2,start_cursor = rev_cursor2)
pprint.pprint(bars3)

$ b $(b




$ b

上面的代码打印出以下结果;请注意,结果的第三页只是第二页翻转,而不是回到第一页:

  [Bar( key = Key('Bar',4996180836614144),foo = u'a'),
Bar(key = Key('Bar',6122080743456768),foo = u'b')]
[Bar (key = Key('Bar',6685030696878080),foo = u'd')]
[key = Key('Bar',5559130790035456),foo = u'c'),
Bar Bar(key = Key('Bar',6685030696878080),foo = u'd'),
Bar(key = Key('Bar',5559130790035456),foo = u'c')]

我期待看到像这样的结果:



<$ p $ (key = Key('Bar',6122080743456768),foo = u('bar',4996180836614144),foo = u'a'),
Bar 'b')]
Bar(key = Key('Bar',5559130790035456),foo = u'c'),
Bar(key = Key('Bar',6685030696878080),foo = '']]
[Bar(key = Key('Bar',6685030696878080),foo = u'a'),
Bar(key = Key('Bar',5559130790035456),foo = u'b')]

如果我将代码的获取前一页部分更改为以下代码段,我会得到预期的输出结果,但是我是否存在任何缺点是否愿意使用正向查询和end_cursor而不是文档中描述的机制?

 #获取上一页。 
bars3,cursor3,more3 = q_forward.fetch_page(2,end_cursor = cursor1)
pprint.pprint(bars3)


解决方案

为了让文档中的示例更清晰一点,让我们暂时忘记数据存储,并使用列表来处理:

 #some_list = [4,6,1,12,15,0,3,7,10,11,8,2,9,14, 5,13] 

#设置。
q = Bar.query()

q_forward = q.order(Bar.key)
#这会将我们列表的元素按以下顺序排列:
# ordered_list = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]

q_reverse = q.order( - Bar.key)
#现在我们颠倒了向后分页的顺序:
#reversed_list = [ 3,2,1,0]

#前进一页。

bars,cursor,more = q_forward.fetch_page(10)
#这将获取ordered_list(!)
#中的前10个元素,并产生以下结果:
#bars = [0,1,2,3,4,5,6,7,8,9]
#cursor = [... 9,CURSOR-> 10 ...]
#more = True
#请注意右边的光标。

#获取相同的页面后退。

rev_cursor = cursor.reversed()
#现在光标向左:
#rev_cursor = [... 9,< -CURSOR 10 ... ]

bars1,cursor1,more1 = q_reverse.fetch_page(10,start_cursor = rev_cursor)
#使用reversed_list(!),从rev_cursor开始并获取
#前十元素:
#bars1 = [9,8,7,6,5,4,3,2,1,0]

因此,文档中的示例以两个不同的顺序从两个不同的方向提取相同的页面。这不是你想达到的目的。



看来你已经找到了一个解决方案,可以很好地覆盖你的用例,但是让我推荐另一个:



只需重新使用cursor1返回到page2。

如果我们正在说前端并且当前页面是page3,则这意味着将cursor3分配给'next'按钮和cursor1到'previous'按钮。

这样你就不必颠倒查询和游标。


I'm working on providing an API via GAE that will allow users to page forwards and backwards through a set of entities. I've reviewed the section about cursors on the NDB Queries documentation page, which includes some sample code that describes how to page backwards through query results, but it doesn't seem to be working as desired. I'm using GAE Development SDK 1.8.8.

Here's a modified version of that example that creates 5 sample entities, gets and prints the first page, steps forward into and prints the second page, and attempts to step backwards and print the first page again:

import pprint
from google.appengine.ext import ndb

class Bar(ndb.Model):
    foo = ndb.StringProperty()

#ndb.put_multi([Bar(foo="a"), Bar(foo="b"), Bar(foo="c"), Bar(foo="d"), Bar(foo="e")])

# Set up.
q = Bar.query()
q_forward = q.order(Bar.foo)
q_reverse = q.order(-Bar.foo)

# Fetch the first page.
bars1, cursor1, more1 = q_forward.fetch_page(2)
pprint.pprint(bars1)

# Fetch the next (2nd) page.
bars2, cursor2, more2 = q_forward.fetch_page(2, start_cursor=cursor1)
pprint.pprint(bars2)

# Fetch the previous page.
rev_cursor2 = cursor2.reversed()
bars3, cursor3, more3 = q_reverse.fetch_page(2, start_cursor=rev_cursor2)
pprint.pprint(bars3)

(FYI, you can run the above in the Interactive Console of your local app engine.)

The above code prints the following results; note that the third page of results is just the second page reversed, instead of going back to the first page:

[Bar(key=Key('Bar', 4996180836614144), foo=u'a'),
 Bar(key=Key('Bar', 6122080743456768), foo=u'b')]
[Bar(key=Key('Bar', 5559130790035456), foo=u'c'),
 Bar(key=Key('Bar', 6685030696878080), foo=u'd')]
[Bar(key=Key('Bar', 6685030696878080), foo=u'd'),
 Bar(key=Key('Bar', 5559130790035456), foo=u'c')]

I was expecting to see results like this:

[Bar(key=Key('Bar', 4996180836614144), foo=u'a'),
 Bar(key=Key('Bar', 6122080743456768), foo=u'b')]
[Bar(key=Key('Bar', 5559130790035456), foo=u'c'),
 Bar(key=Key('Bar', 6685030696878080), foo=u'd')]
[Bar(key=Key('Bar', 6685030696878080), foo=u'a'),
 Bar(key=Key('Bar', 5559130790035456), foo=u'b')]

If I change the "Fetch the previous page" section of code to the following code snippet, I get the expected output, but are there any drawbacks that I haven't forseen to using the forward-ordered query and end_cursor instead of the mechanism described in the documentation?

# Fetch the previous page.
bars3, cursor3, more3 = q_forward.fetch_page(2, end_cursor=cursor1)
pprint.pprint(bars3)

解决方案

To make the example from the docs a little clearer let's forget about the datastore for a moment and work with a list instead:

# some_list = [4, 6, 1, 12, 15, 0, 3, 7, 10, 11, 8, 2, 9, 14, 5, 13]

# Set up.
q = Bar.query()

q_forward = q.order(Bar.key)
# This puts the elements of our list into the following order:
# ordered_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

q_reverse = q.order(-Bar.key)
# Now we reversed the order for backwards paging: 
# reversed_list = [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

# Fetch a page going forward.

bars, cursor, more = q_forward.fetch_page(10)
# This fetches the first 10 elements from ordered_list(!) 
# and yields the following:
# bars = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# cursor = [... 9, CURSOR-> 10 ...]
# more = True
# Please notice the right-facing cursor.

# Fetch the same page going backward.

rev_cursor = cursor.reversed()
# Now the cursor is facing to the left:
# rev_cursor = [... 9, <-CURSOR 10 ...]

bars1, cursor1, more1 = q_reverse.fetch_page(10, start_cursor=rev_cursor)
# This uses reversed_list(!), starts at rev_cursor and fetches 
# the first ten elements to it's left:
# bars1 = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

So the example from the docs fetches the same page from two different directions in two differents orders. This is not what you want to achieve.

It seems you already found a solution that covers your use case pretty well but let me suggest another:

Simply reuse cursor1 to go back to page2.
If we're talking frontend and the current page is page3, this would mean assigning cursor3 to the 'next'-button and cursor1 to the 'previous'-button.

That way you have to reverse neither the query nor the cursor(s).

这篇关于在给定NDB游标的情况下,获取结果的上一页的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆