2727
2828from google .cloud .ndb import context as context_module
2929from google .cloud .ndb import _eventloop
30+ from google .cloud .ndb import _options
3031from google .cloud .ndb import _remote
3132from google .cloud .ndb import _retry
3233from google .cloud .ndb import tasklets
@@ -105,7 +106,7 @@ def rpc_call():
105106 return rpc_call ()
106107
107108
108- def lookup (key , ** options ):
109+ def lookup (key , options ):
109110 """Look up a Datastore entity.
110111
111112 Gets an entity from Datastore, asynchronously. Actually adds the request to
@@ -114,15 +115,13 @@ def lookup(key, **options):
114115
115116 Args:
116117 key (~datastore.Key): The key for the entity to retrieve.
117- options (Dict[str, Any] ): The options for the request. For example,
118- ``{"read_consistency": EVENTUAL}``.
118+ options (_options.ReadOptions ): The options for the request. For
119+ example, ``{"read_consistency": EVENTUAL}``.
119120
120121 Returns:
121122 :class:`~tasklets.Future`: If not an exception, future's result will be
122123 either an entity protocol buffer or _NOT_FOUND.
123124 """
124- _check_unsupported_options (options )
125-
126125 batch = _get_batch (_LookupBatch , options )
127126 return batch .add (key )
128127
@@ -138,9 +137,8 @@ def _get_batch(batch_cls, options):
138137 Args:
139138 batch_cls (type): Class representing the kind of operation being
140139 batched.
141- options (Dict[str, Any]): The options for the request. For example,
142- ``{"read_consistency": EVENTUAL}``. Calls with different options
143- will be placed in different batches.
140+ options (_options.ReadOptions): The options for the request. Calls with
141+ different options will be placed in different batches.
144142
145143 Returns:
146144 batch_cls: An instance of the batch class.
@@ -150,7 +148,15 @@ def _get_batch(batch_cls, options):
150148 if batches is None :
151149 context .batches [batch_cls ] = batches = {}
152150
153- options_key = tuple (sorted (options .items ()))
151+ options_key = tuple (
152+ sorted (
153+ (
154+ (key , value )
155+ for key , value in options .items ()
156+ if value is not None
157+ )
158+ )
159+ )
154160 batch = batches .get (options_key )
155161 if batch is not None :
156162 return batch
@@ -173,9 +179,8 @@ class _LookupBatch:
173179 protocol buffers to dependent futures.
174180
175181 Args:
176- options (Dict[str, Any]): The options for the request. For example,
177- ``{"read_consistency": EVENTUAL}``. Calls with different options
178- will be placed in different batches.
182+ options (_options.ReadOptions): The options for the request. Calls with
183+ different options will be placed in different batches.
179184 """
180185
181186 def __init__ (self , options ):
@@ -205,7 +210,7 @@ def idle_callback(self):
205210 keys .append (key_pb )
206211
207212 read_options = _get_read_options (self .options )
208- retries = self .options .get ( " retries" )
213+ retries = self .options .retries
209214 rpc = _datastore_lookup (keys , read_options , retries = retries )
210215 rpc .add_done_callback (self .lookup_callback )
211216
@@ -288,10 +293,9 @@ def _get_read_options(options):
288293 """Get the read options for a request.
289294
290295 Args:
291- options (Dict[str, Any]): The options for the request. For example,
292- ``{"read_consistency": EVENTUAL}``. May contain options unrelated
293- to creating a :class:`datastore_pb2.ReadOptions` instance, which
294- will be ignored.
296+ options (_options.ReadOptions): The options for the request. May
297+ contain options unrelated to creating a
298+ :class:`datastore_pb2.ReadOptions` instance, which will be ignored.
295299
296300 Returns:
297301 datastore_pb2.ReadOptions: The options instance for passing to the
@@ -303,13 +307,11 @@ def _get_read_options(options):
303307 """
304308 transaction = _get_transaction (options )
305309
306- read_consistency = options .get ("read_consistency" )
307- if read_consistency is None :
308- read_consistency = options .get ("read_policy" ) # Legacy NDB
310+ read_consistency = options .read_consistency
309311
310312 if transaction is not None and read_consistency is EVENTUAL :
311313 raise ValueError (
312- "read_consistency must be EVENTUAL when in transaction"
314+ "read_consistency must not be EVENTUAL when in transaction"
313315 )
314316
315317 return datastore_pb2 .ReadOptions (
@@ -324,25 +326,29 @@ def _get_transaction(options):
324326 it will return the transaction for the current context.
325327
326328 Args:
327- options (Dict[str, Any] ): The options for the request. Only
329+ options (_options.ReadOptions ): The options for the request. Only
328330 ``transaction`` will have any bearing here.
329331
330332 Returns:
331333 Union[bytes, NoneType]: The transaction identifier, or :data:`None`.
332334 """
333- context = context_module .get_context ()
334- return options .get ("transaction" , context .transaction )
335+ transaction = getattr (options , "transaction" , None )
336+ if transaction is None :
337+ context = context_module .get_context ()
338+ transaction = context .transaction
339+
340+ return transaction
335341
336342
337- def put (entity_pb , ** options ):
343+ def put (entity_pb , options ):
338344 """Store an entity in datastore.
339345
340346 The entity can be a new entity to be saved for the first time or an
341347 existing entity that has been updated.
342348
343349 Args:
344350 entity_pb (datastore_v1.types.Entity): The entity to be stored.
345- options (Dict[str, Any] ): Options for this request.
351+ options (_options.Options ): Options for this request.
346352
347353 Returns:
348354 tasklets.Future: Result will be completed datastore key
@@ -357,15 +363,15 @@ def put(entity_pb, **options):
357363 return batch .put (entity_pb )
358364
359365
360- def delete (key , ** options ):
366+ def delete (key , options ):
361367 """Delete an entity from Datastore.
362368
363369 Deleting an entity that doesn't exist does not result in an error. The
364370 result is the same regardless.
365371
366372 Args:
367373 key (datastore.Key): The key for the entity to be deleted.
368- options (Dict[str, Any] ): Options for this request.
374+ options (_options.Options ): Options for this request.
369375
370376 Returns:
371377 tasklets.Future: Will be finished when entity is deleted. Result will
@@ -384,20 +390,19 @@ class _NonTransactionalCommitBatch:
384390 """Batch for tracking a set of mutations for a non-transactional commit.
385391
386392 Attributes:
387- options (Dict[str, Any] ): See Args.
393+ options (_options.Options ): See Args.
388394 mutations (List[datastore_pb2.Mutation]): Sequence of mutation protocol
389395 buffers accumumlated for this batch.
390396 futures (List[tasklets.Future]): Sequence of futures for return results
391397 of the commit. The i-th element of ``futures`` corresponds to the
392398 i-th element of ``mutations``.
393399
394400 Args:
395- options (Dict[str, Any] ): The options for the request. Calls with
401+ options (_options.Options ): The options for the request. Calls with
396402 different options will be placed in different batches.
397403 """
398404
399405 def __init__ (self , options ):
400- _check_unsupported_options (options )
401406 self .options = options
402407 self .mutations = []
403408 self .futures = []
@@ -441,7 +446,7 @@ def idle_callback(self):
441446 def commit_callback (rpc ):
442447 _process_commit (rpc , futures )
443448
444- retries = self .options .get ( " retries" )
449+ retries = self .options .retries
445450 rpc = _datastore_commit (self .mutations , None , retries = retries )
446451 rpc .add_done_callback (commit_callback )
447452
@@ -459,7 +464,7 @@ def commit(transaction, retries=None):
459464 tasklets.Future: Result will be none, will finish when the transaction
460465 is committed.
461466 """
462- batch = _get_commit_batch (transaction , {} )
467+ batch = _get_commit_batch (transaction , _options . Options () )
463468 return batch .commit (retries = retries )
464469
465470
@@ -469,27 +474,26 @@ def _get_commit_batch(transaction, options):
469474 Args:
470475 transaction (bytes): The transaction id. Different transactions will
471476 have different batchs.
472- options (Dict[str, Any] ): Options for the batch. Only "transaction" is
473- supported at this time.
477+ options (_options.Options ): Options for the batch. Not supported at
478+ this time.
474479
475480 Returns:
476481 _TransactionalCommitBatch: The batch.
477482 """
478483 # Support for different options will be tricky if we're in a transaction,
479484 # since we can only do one commit, so any options that affect that gRPC
480- # call would all need to be identical. For now, only "transaction" is
481- # suppoorted if there is a transaction.
482- options = options .copy ()
483- options .pop ("transaction" , None )
484- for key in options :
485- raise NotImplementedError ("Passed bad option: {!r}" .format (key ))
485+ # call would all need to be identical. For now, no options are supported
486+ # here.
487+ for key , value in options .items ():
488+ if value :
489+ raise NotImplementedError ("Passed bad option: {!r}" .format (key ))
486490
487491 # Since we're in a transaction, we need to hang on to the batch until
488492 # commit time, so we need to store it separately from other batches.
489493 context = context_module .get_context ()
490494 batch = context .commit_batches .get (transaction )
491495 if batch is None :
492- batch = _TransactionalCommitBatch ({ " transaction" : transaction } )
496+ batch = _TransactionalCommitBatch (transaction , options )
493497 context .commit_batches [transaction ] = batch
494498
495499 return batch
@@ -499,14 +503,14 @@ class _TransactionalCommitBatch(_NonTransactionalCommitBatch):
499503 """Batch for tracking a set of mutations to be committed for a transaction.
500504
501505 Attributes:
502- options (Dict[str, Any] ): See Args.
506+ options (_options.Options ): See Args.
503507 mutations (List[datastore_pb2.Mutation]): Sequence of mutation protocol
504508 buffers accumumlated for this batch.
505509 futures (List[tasklets.Future]): Sequence of futures for return results
506510 of the commit. The i-th element of ``futures`` corresponds to the
507511 i-th element of ``mutations``.
508512 transaction (bytes): The transaction id of the transaction for this
509- commit, if in a transaction .
513+ commit.
510514 allocating_ids (List[tasklets.Future]): Futures for any calls to
511515 AllocateIds that are fired off before commit.
512516 incomplete_mutations (List[datastore_pb2.Mutation]): List of mutations
@@ -519,13 +523,15 @@ class _TransactionalCommitBatch(_NonTransactionalCommitBatch):
519523 receive results of id allocation.
520524
521525 Args:
522- options (Dict[str, Any]): The options for the request. Calls with
526+ transaction (bytes): The transaction id of the transaction for this
527+ commit.
528+ options (_options.Options): The options for the request. Calls with
523529 different options will be placed in different batches.
524530 """
525531
526- def __init__ (self , options ):
532+ def __init__ (self , transaction , options ):
527533 super (_TransactionalCommitBatch , self ).__init__ (options )
528- self .transaction = _get_transaction ( options )
534+ self .transaction = transaction
529535 self .allocating_ids = []
530536 self .incomplete_mutations = []
531537 self .incomplete_futures = []
@@ -582,7 +588,7 @@ def callback(rpc):
582588 # Signal that we're done allocating these ids
583589 allocating_ids .set_result (None )
584590
585- retries = self .options .get ( " retries" )
591+ retries = self .options .retries
586592 keys = [mutation .upsert .key for mutation in mutations ]
587593 rpc = _datastore_allocate_ids (keys , retries = retries )
588594 rpc .add_done_callback (callback )
@@ -612,8 +618,9 @@ def commit(self, retries=None):
612618
613619 Args:
614620 retries (int): Number of times to potentially retry the call. If
615- :data:`None` is passed, will use :data:`_retry._DEFAULT_RETRIES`.
616- If :data:`0` is passed, the call is attempted only once.
621+ :data:`None` is passed, will use
622+ :data:`_retry._DEFAULT_RETRIES`. If :data:`0` is passed, the
623+ call is attempted only once.
617624 """
618625 if not self .mutations :
619626 return
@@ -851,46 +858,3 @@ def _datastore_rollback(transaction, retries=None):
851858 )
852859
853860 return make_call ("Rollback" , request , retries = retries )
854-
855-
856- _OPTIONS_SUPPORTED = {
857- "transaction" ,
858- "read_consistency" ,
859- "read_policy" ,
860- "retries" ,
861- }
862-
863- _OPTIONS_NOT_IMPLEMENTED = {
864- "deadline" ,
865- "force_writes" ,
866- "use_cache" ,
867- "use_memcache" ,
868- "use_datastore" ,
869- "memcache_timeout" ,
870- "max_memcache_items" ,
871- "xg" ,
872- "propagation" ,
873- "retries" ,
874- }
875-
876-
877- def _check_unsupported_options (options ):
878- """Check to see if any passed options are not supported.
879-
880- options (Dict[str, Any]): The options for the request. For example,
881- ``{"read_consistency": EVENTUAL}``.
882-
883- Raises: NotImplementedError if any options are not supported.
884- """
885- for key in options :
886- if key in _OPTIONS_NOT_IMPLEMENTED :
887- # option is used in Legacy NDB, but has not yet been implemented in
888- # the rewrite, nor have we determined it won't be used, yet.
889- raise NotImplementedError (
890- "Support for option {!r} has not yet been implemented" .format (
891- key
892- )
893- )
894-
895- elif key not in _OPTIONS_SUPPORTED :
896- raise NotImplementedError ("Passed bad option: {!r}" .format (key ))
0 commit comments