2

Is code bellow from backward cursor will be compatible?

This is advance question since it is related to undocumented feature of *.db and Google App Engine - maybe it against some documention of cursor()! https://developers.google.com/appengine/docs/python/datastore/queryclass?hl=pl#Query_fetch

Whatever following documentation ... future invocation of the same query ... not will give backward cursor feature. I was inverted direction of query to go backward.

I was study Guido example for ndb.* and found that reverse cursor could be implemented in db.* with use some tricks used in ndb.* for cursor.reserve() (+/-)! Backward pagination with cursor is working but missing an item

So query is DeleteMe.all().order('rank') and inverted is DeleteMe.all().order('-rank'). I assume that before sort we could apply some filters and it will still use same index scan.

Now is code doing real backward cursor in db.* which I want to confirm will be compatible - if it possible.

messages = []

class DeleteMe(db.Model):
  rank = db.IntegerProperty()

db.delete(DeleteMe.all(keys_only=True))

for rank in range(50):
  e = DeleteMe(rank = rank)
  e.put()

messages.append('forward +5')     
q = DeleteMe.all().order('rank')
r = q.fetch(5)
for e in r:
  messages.append(e.rank)
endCursor = q.cursor()
messages.append('end to %s' % endCursor)

messages.append('forward +5')
startCursor = endCursor
messages.append('start from %s' % startCursor)     
q = DeleteMe.all().order('rank').with_cursor(startCursor)
r = q.fetch(1)
# 1st trick
backwardCursor = q.cursor()
messages.append('backward cursor %s' % backwardCursor)
q.with_cursor(backwardCursor)
r.extend(q.fetch(5-1))
for e in r:
  messages.append(e.rank)
endCursor = q.cursor()
messages.append('end to %s' % endCursor)

messages.append('backward +5')
startCursor = backwardCursor 
messages.append('modified start from %s' % startCursor)     
# 2st trick
q = DeleteMe.all().order('-rank').with_cursor(startCursor)
r = q.fetch(5)
for e in r:
  messages.append(e.rank)
endCursor = q.cursor()
messages.append('end to %s' % endCursor)

And result of working backward cursor:

forward +5
0
1
2
3
4
end to E-ABAOsB8gEEcmFua_oBAggE7AGCAhxqCGVyZXN0MjRochALEghEZWxldGVNZRjNnQYMFA==
forward +5
start from E-ABAOsB8gEEcmFua_oBAggE7AGCAhxqCGVyZXN0MjRochALEghEZWxldGVNZRjNnQYMFA==
backward cursor E-ABAOsB8gEEcmFua_oBAggF7AGCAhxqCGVyZXN0MjRochALEghEZWxldGVNZRjOnQYMFA==
5
6
7
8
9
end to E-ABAOsB8gEEcmFua_oBAggJ7AGCAhxqCGVyZXN0MjRochALEghEZWxldGVNZRjSnQYMFA==
backward +5
modified start from E-ABAOsB8gEEcmFua_oBAggF7AGCAhxqCGVyZXN0MjRochALEghEZWxldGVNZRjOnQYMFA==
4
3
2
1
0
end to E-ABAOsB8gEEcmFua_oBAggA7AGCAhxqCGVyZXN0MjRochALEghEZWxldGVNZRjJnQYMFA==

The is little long but should be. Please give some hint if such use of db.* is safe since it allow very fast paging.

Community
  • 1
  • 1
Chameleon
  • 9,722
  • 16
  • 65
  • 127

1 Answers1

1

I don't think this is how you're supposed to do it. When using a backward cursor you should also use a reverse query -- in your case that would mean order('-rank').

Guido van Rossum
  • 16,690
  • 3
  • 46
  • 49