Skip to content

Commit 2a10609

Browse files
drewismejpinner-lyft
authored andcommitted
Fix exclusive_start_key getting lost in PageIterator (pynamodb#421)
1 parent 01d0b59 commit 2a10609

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

pynamodb/pagination.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def __init__(self, operation, args, kwargs):
1313
self._args = args
1414
self._kwargs = kwargs
1515
self._first_iteration = True
16-
self._last_evaluated_key = None
16+
self._last_evaluated_key = kwargs.get('exclusive_start_key')
1717
self._total_scanned_count = 0
1818

1919
def __iter__(self):
@@ -110,11 +110,8 @@ def next(self):
110110

111111
@property
112112
def last_evaluated_key(self):
113-
if self._first_iteration:
114-
# Not started iterating yet: there cannot be a last_evaluated_key
115-
return None
116-
117-
if self._index == self._count:
113+
if self._first_iteration or self._index == self._count:
114+
# Not started iterating yet: return `exclusive_start_key` if set, otherwise expect None; or,
118115
# Entire page has been consumed: last_evaluated_key is whatever DynamoDB returned
119116
# It may correspond to the current item, or it may correspond to an item evaluated but not returned.
120117
return self.page_iter.last_evaluated_key

pynamodb/tests/test_model.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,32 @@ def test_query_limit_greater_than_available_items_and_page_size(self):
22242224
self.assertEquals(results_iter.total_count, 30)
22252225
self.assertEquals(results_iter.page_iter.total_scanned_count, 60)
22262226

2227+
def test_query_with_exclusive_start_key(self):
2228+
with patch(PATCH_METHOD) as req:
2229+
req.return_value = MODEL_TABLE_DATA
2230+
UserModel('foo', 'bar')
2231+
2232+
with patch(PATCH_METHOD) as req:
2233+
items = []
2234+
for idx in range(30):
2235+
item = copy.copy(GET_MODEL_ITEM_DATA.get(ITEM))
2236+
item['user_id'] = {STRING_SHORT: 'id-{0}'.format(idx)}
2237+
items.append(item)
2238+
2239+
req.side_effect = [
2240+
{'Count': 10, 'ScannedCount': 10, 'Items': items[10:20], 'LastEvaluatedKey': {'user_id': items[19]['user_id']}},
2241+
]
2242+
results_iter = UserModel.query('foo', limit=10, page_size=10, last_evaluated_key={'user_id': items[9]['user_id']})
2243+
self.assertEquals(results_iter.last_evaluated_key, {'user_id': items[9]['user_id']})
2244+
2245+
results = list(results_iter)
2246+
self.assertEqual(len(results), 10)
2247+
self.assertEqual(len(req.mock_calls), 1)
2248+
self.assertEquals(req.mock_calls[0][1][1]['Limit'], 10)
2249+
self.assertEquals(results_iter.last_evaluated_key, {'user_id': items[19]['user_id']})
2250+
self.assertEquals(results_iter.total_count, 10)
2251+
self.assertEquals(results_iter.page_iter.total_scanned_count, 10)
2252+
22272253
def test_query(self):
22282254
"""
22292255
Model.query

0 commit comments

Comments
 (0)