1- from pynamodb .constants import CAMEL_COUNT , ITEMS , LAST_EVALUATED_KEY
1+ from pynamodb .constants import CAMEL_COUNT , ITEMS , LAST_EVALUATED_KEY , SCANNED_COUNT
22
33
4- class ResultIterator (object ):
4+ class PageIterator (object ):
55 """
6- ResultIterator handles Query and Scan result pagination.
6+ PageIterator handles Query and Scan result pagination.
77
88 http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.Pagination
99 http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.Pagination
1010 """
11- def __init__ (self , operation , args , kwargs , map_fn = None , limit = None ):
11+ def __init__ (self , operation , args , kwargs ):
1212 self ._operation = operation
1313 self ._args = args
1414 self ._kwargs = kwargs
15+ self ._first_iteration = True
16+ self ._last_evaluated_key = None
17+ self ._total_scanned_count = 0
18+
19+ def __iter__ (self ):
20+ return self
21+
22+ def __next__ (self ):
23+ if self ._last_evaluated_key is None and not self ._first_iteration :
24+ raise StopIteration ()
25+
26+ self ._first_iteration = False
27+
28+ self ._kwargs ['exclusive_start_key' ] = self ._last_evaluated_key
29+ page = self ._operation (* self ._args , ** self ._kwargs )
30+ self ._last_evaluated_key = page .get (LAST_EVALUATED_KEY )
31+ self ._total_scanned_count += page [SCANNED_COUNT ]
32+
33+ return page
34+
35+ def next (self ):
36+ return self .__next__ ()
37+
38+ @property
39+ def page_size (self ):
40+ return self ._kwargs .get ('limit' )
41+
42+ @page_size .setter
43+ def page_size (self , page_size ):
44+ self ._kwargs ['limit' ] = page_size
45+
46+ @property
47+ def last_evaluated_key (self ):
48+ return self ._last_evaluated_key
49+
50+ @property
51+ def total_scanned_count (self ):
52+ return self ._total_scanned_count
53+
54+
55+ class ResultIterator (object ):
56+ """
57+ ResultIterator handles Query and Scan item pagination.
58+
59+ http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.Pagination
60+ http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.Pagination
61+ """
62+ def __init__ (self , operation , args , kwargs , map_fn = None , limit = None ):
63+ self .page_iter = PageIterator (operation , args , kwargs )
64+ self ._first_iteration = True
1565 self ._map_fn = map_fn
1666 self ._limit = limit
17- self ._needs_execute = True
1867 self ._total_count = 0
1968
20- def _execute (self ):
21- data = self ._operation (* self ._args , ** self ._kwargs )
22- self ._count = data [CAMEL_COUNT ]
23- self ._items = data .get (ITEMS ) # not returned if 'Select' is set to 'COUNT'
24- self ._last_evaluated_key = data .get (LAST_EVALUATED_KEY )
69+ def _get_next_page (self ):
70+ page = next (self .page_iter )
71+ self ._count = page [CAMEL_COUNT ]
72+ self ._items = page .get (ITEMS ) # not returned if 'Select' is set to 'COUNT'
2573 self ._index = 0 if self ._items else self ._count
2674 self ._total_count += self ._count
2775
@@ -32,16 +80,12 @@ def __next__(self):
3280 if self ._limit == 0 :
3381 raise StopIteration
3482
35- if self ._needs_execute :
36- self ._needs_execute = False
37- self ._execute ()
38-
39- while self ._index == self ._count and self ._last_evaluated_key :
40- self ._kwargs ['exclusive_start_key' ] = self ._last_evaluated_key
41- self ._execute ()
83+ if self ._first_iteration :
84+ self ._first_iteration = False
85+ self ._get_next_page ()
4286
43- if self ._index == self ._count :
44- raise StopIteration
87+ while self ._index == self ._count :
88+ self . _get_next_page ()
4589
4690 item = self ._items [self ._index ]
4791 self ._index += 1
@@ -56,7 +100,7 @@ def next(self):
56100
57101 @property
58102 def last_evaluated_key (self ):
59- return self ._last_evaluated_key
103+ return self .page_iter . last_evaluated_key
60104
61105 @property
62106 def total_count (self ):
0 commit comments