1919from google .api_core import page_iterator
2020from google .cloud ._helpers import _ensure_tuple_or_list
2121
22- from google .cloud .datastore_v1 .proto import datastore_pb2 as _datastore_pb2
23- from google .cloud .datastore_v1 .proto import entity_pb2 as _entity_pb2
24- from google .cloud .datastore_v1 .proto import query_pb2 as _query_pb2
22+ from google .cloud .datastore_v1 .proto import entity_pb2
23+ from google .cloud .datastore_v1 .proto import query_pb2
2524from google .cloud .datastore import helpers
2625from google .cloud .datastore .key import Key
2726
2827
29- _NOT_FINISHED = _query_pb2 .QueryResultBatch .NOT_FINISHED
28+ _NOT_FINISHED = query_pb2 .QueryResultBatch .NOT_FINISHED
3029
3130_FINISHED = (
32- _query_pb2 .QueryResultBatch .NO_MORE_RESULTS ,
33- _query_pb2 .QueryResultBatch .MORE_RESULTS_AFTER_LIMIT ,
34- _query_pb2 .QueryResultBatch .MORE_RESULTS_AFTER_CURSOR ,
31+ query_pb2 .QueryResultBatch .NO_MORE_RESULTS ,
32+ query_pb2 .QueryResultBatch .MORE_RESULTS_AFTER_LIMIT ,
33+ query_pb2 .QueryResultBatch .MORE_RESULTS_AFTER_CURSOR ,
3534)
3635
3736
@@ -81,11 +80,11 @@ class Query(object):
8180 """
8281
8382 OPERATORS = {
84- '<=' : _query_pb2 .PropertyFilter .LESS_THAN_OR_EQUAL ,
85- '>=' : _query_pb2 .PropertyFilter .GREATER_THAN_OR_EQUAL ,
86- '<' : _query_pb2 .PropertyFilter .LESS_THAN ,
87- '>' : _query_pb2 .PropertyFilter .GREATER_THAN ,
88- '=' : _query_pb2 .PropertyFilter .EQUAL ,
83+ '<=' : query_pb2 .PropertyFilter .LESS_THAN_OR_EQUAL ,
84+ '>=' : query_pb2 .PropertyFilter .GREATER_THAN_OR_EQUAL ,
85+ '<' : query_pb2 .PropertyFilter .LESS_THAN ,
86+ '>' : query_pb2 .PropertyFilter .GREATER_THAN ,
87+ '=' : query_pb2 .PropertyFilter .EQUAL ,
8988 }
9089 """Mapping of operator strings and their protobuf equivalents."""
9190
@@ -331,7 +330,7 @@ def distinct_on(self, value):
331330 self ._distinct_on [:] = value
332331
333332 def fetch (self , limit = None , offset = 0 , start_cursor = None , end_cursor = None ,
334- client = None ):
333+ client = None , eventual = False ):
335334 """Execute the Query; return an iterator for the matching entities.
336335
337336 For example::
@@ -358,18 +357,28 @@ def fetch(self, limit=None, offset=0, start_cursor=None, end_cursor=None,
358357 :param end_cursor: (Optional) cursor passed through to the iterator.
359358
360359 :type client: :class:`google.cloud.datastore.client.Client`
361- :param client: client used to connect to datastore.
360+ :param client: (Optional) client used to connect to datastore.
362361 If not supplied, uses the query's value.
363362
363+ :type eventual: bool
364+ :param eventual: (Optional) Defaults to strongly consistent (False).
365+ Setting True will use eventual consistency,
366+ but cannot be used inside a transaction or
367+ will raise ValueError.
368+
364369 :rtype: :class:`Iterator`
365370 :returns: The iterator for the query.
366371 """
367372 if client is None :
368373 client = self ._client
369374
370- return Iterator (
371- self , client , limit = limit , offset = offset ,
372- start_cursor = start_cursor , end_cursor = end_cursor )
375+ return Iterator (self ,
376+ client ,
377+ limit = limit ,
378+ offset = offset ,
379+ start_cursor = start_cursor ,
380+ end_cursor = end_cursor ,
381+ eventual = eventual )
373382
374383
375384class Iterator (page_iterator .Iterator ):
@@ -396,18 +405,25 @@ class Iterator(page_iterator.Iterator):
396405 :type end_cursor: bytes
397406 :param end_cursor: (Optional) Cursor to end paging through
398407 query results.
408+
409+ :type eventual: bool
410+ :param eventual: (Optional) Defaults to strongly consistent (False).
411+ Setting True will use eventual consistency,
412+ but cannot be used inside a transaction or
413+ will raise ValueError.
399414 """
400415
401416 next_page_token = None
402417
403418 def __init__ (self , query , client , limit = None , offset = None ,
404- start_cursor = None , end_cursor = None ):
419+ start_cursor = None , end_cursor = None , eventual = False ):
405420 super (Iterator , self ).__init__ (
406421 client = client , item_to_value = _item_to_entity ,
407422 page_token = start_cursor , max_results = limit )
408423 self ._query = query
409424 self ._offset = offset
410425 self ._end_cursor = end_cursor
426+ self ._eventual = eventual
411427 # The attributes below will change over the life of the iterator.
412428 self ._more_results = True
413429 self ._skipped_results = 0
@@ -483,12 +499,12 @@ def _next_page(self):
483499 query_pb = self ._build_protobuf ()
484500 transaction = self .client .current_transaction
485501 if transaction is None :
486- read_options = _datastore_pb2 . ReadOptions ()
502+ transaction_id = None
487503 else :
488- read_options = _datastore_pb2 . ReadOptions (
489- transaction = transaction . id )
504+ transaction_id = transaction . id
505+ read_options = helpers . get_read_options ( self . _eventual , transaction_id )
490506
491- partition_id = _entity_pb2 .PartitionId (
507+ partition_id = entity_pb2 .PartitionId (
492508 project_id = self ._query .project ,
493509 namespace_id = self ._query .namespace )
494510 response_pb = self .client ._datastore_api .run_query (
@@ -512,7 +528,7 @@ def _pb_from_query(query):
512528 it does not contain "in-flight" fields for ongoing query
513529 executions (cursors, offset, limit).
514530 """
515- pb = _query_pb2 .Query ()
531+ pb = query_pb2 .Query ()
516532
517533 for projection_name in query .projection :
518534 pb .projection .add ().property .name = projection_name
@@ -521,15 +537,15 @@ def _pb_from_query(query):
521537 pb .kind .add ().name = query .kind
522538
523539 composite_filter = pb .filter .composite_filter
524- composite_filter .op = _query_pb2 .CompositeFilter .AND
540+ composite_filter .op = query_pb2 .CompositeFilter .AND
525541
526542 if query .ancestor :
527543 ancestor_pb = query .ancestor .to_protobuf ()
528544
529545 # Filter on __key__ HAS_ANCESTOR == ancestor.
530546 ancestor_filter = composite_filter .filters .add ().property_filter
531547 ancestor_filter .property .name = '__key__'
532- ancestor_filter .op = _query_pb2 .PropertyFilter .HAS_ANCESTOR
548+ ancestor_filter .op = query_pb2 .PropertyFilter .HAS_ANCESTOR
533549 ancestor_filter .value .key_value .CopyFrom (ancestor_pb )
534550
535551 for property_name , operator , value in query .filters :
0 commit comments