Skip to content

Commit 421c152

Browse files
author
Srinath Narayanan
authored
fixed bug in querying by page using continuation token (#13298)
* fixed bug in querying by page using continuation token * updated changelog * modified changelog * added support from single partition query continuation tokens * fixed linting error * addressed PR comments
1 parent 0feed6e commit 421c152

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

sdk/cosmos/azure-cosmos/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 4.1.1 (unreleased)
2+
3+
**Bug fixes**
4+
- Fixed bug where continuation token is not honored when query_iterable is used to get results by page. Issue #13265.
5+
6+
17
## 4.1.0 (2020-08-10)
28

39
- Added deprecation warning for "lazy" indexing mode. The backend no longer allows creating containers with this mode and will set them to consistent instead.

sdk/cosmos/azure-cosmos/azure/cosmos/_execution_context/base_execution_context.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"""
2525

2626
from collections import deque
27+
import copy
2728
from .. import _retry_utility
2829
from .. import http_constants
2930

@@ -43,13 +44,18 @@ def __init__(self, client, options):
4344
self._client = client
4445
self._options = options
4546
self._is_change_feed = "changeFeed" in options and options["changeFeed"] is True
46-
self._continuation = None
47-
if "continuation" in options and self._is_change_feed:
48-
self._continuation = options["continuation"]
47+
self._continuation = self._get_initial_continuation()
4948
self._has_started = False
5049
self._has_finished = False
5150
self._buffer = deque()
5251

52+
def _get_initial_continuation(self):
53+
if "continuation" in self._options:
54+
if "enableCrossPartitionQuery" in self._options:
55+
raise ValueError("continuation tokens are not supported for cross-partition queries.")
56+
return self._options["continuation"]
57+
return None
58+
5359
def _has_more_pages(self):
5460
return not self._has_started or self._continuation
5561

@@ -112,8 +118,9 @@ def _fetch_items_helper_no_retries(self, fetch_function):
112118
while self._continuation or not self._has_started:
113119
if not self._has_started:
114120
self._has_started = True
115-
self._options["continuation"] = self._continuation
116-
(fetched_items, response_headers) = fetch_function(self._options)
121+
new_options = copy.deepcopy(self._options)
122+
new_options["continuation"] = self._continuation
123+
(fetched_items, response_headers) = fetch_function(new_options)
117124
continuation_key = http_constants.HttpHeaders.Continuation
118125
# Use Etag as continuation token for change feed queries.
119126
if self._is_change_feed:

sdk/cosmos/azure-cosmos/test/test_query.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,42 @@ def test_distinct_on_different_types_and_field_orders(self):
522522
_QueryExecutionContextBase.__next__ = self.OriginalExecuteFunction
523523
_QueryExecutionContextBase.next = self.OriginalExecuteFunction
524524

525+
def test_paging_with_continuation_token(self):
526+
created_collection = self.config.create_multi_partition_collection_with_custom_pk_if_not_exist(self.client)
527+
528+
document_definition = {'pk': 'pk', 'id': '1'}
529+
created_collection.create_item(body=document_definition)
530+
document_definition = {'pk': 'pk', 'id': '2'}
531+
created_collection.create_item(body=document_definition)
532+
533+
query = 'SELECT * from c'
534+
query_iterable = created_collection.query_items(
535+
query=query,
536+
partition_key='pk',
537+
max_item_count=1
538+
)
539+
pager = query_iterable.by_page()
540+
pager.next()
541+
token = pager.continuation_token
542+
second_page = list(pager.next())[0]
543+
544+
pager = query_iterable.by_page(token)
545+
second_page_fetched_with_continuation_token = list(pager.next())[0]
546+
547+
self.assertEqual(second_page['id'], second_page_fetched_with_continuation_token['id'])
548+
549+
def test_cross_partition_query_with_continuation_token_fails(self):
550+
created_collection = self.config.create_multi_partition_collection_with_custom_pk_if_not_exist(self.client)
551+
query = 'SELECT * from c'
552+
query_iterable = created_collection.query_items(
553+
query=query,
554+
enable_cross_partition_query=True,
555+
max_item_count=1,
556+
)
557+
558+
with self.assertRaises(ValueError):
559+
pager = query_iterable.by_page("fake_continuation_token")
560+
525561
def _validate_distinct_on_different_types_and_field_orders(self, collection, query, expected_results, get_mock_result):
526562
self.count = 0
527563
self.get_mock_result = get_mock_result

0 commit comments

Comments
 (0)