From b3f01e921c954cf0abf555ae8f06e0637e8fec3a Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Wed, 7 Aug 2019 13:34:30 -0400 Subject: [PATCH] Update Migration Notes. (#152) Updated Migration Notes. Added ``RedisCache`` to top-level exports (forgot to do this earlier). Moved ``_db_set_value()`` and ``_db_get_value()`` from the several subclasses up to ``model.Property`` so we can not implement them in a single place. Changed some ``NotImplementedError``s into ``NoLongerImplementedError``s to make explicit decision not to implement some old functionality. --- MIGRATION_NOTES.md | 75 ++++++++++++- src/google/cloud/ndb/__init__.py | 2 + src/google/cloud/ndb/context.py | 4 +- src/google/cloud/ndb/model.py | 176 +++---------------------------- 4 files changed, 92 insertions(+), 165 deletions(-) diff --git a/MIGRATION_NOTES.md b/MIGRATION_NOTES.md index 1a5dfa28..a564f5b2 100644 --- a/MIGRATION_NOTES.md +++ b/MIGRATION_NOTES.md @@ -36,10 +36,43 @@ from google.cloud import ndb # Assume GOOGLE_APPLICATION_CREDENTIALS is set in environment client = ndb.Client() -with context as client.context(): +with client.context() as context: do_stuff_with_ndb() ``` +## Memcache + +Because the Google App Engine Memcache service is not a part of the Google +Cloud Platform, it was necessary to refactor the "memcache" functionality of +NDB. The concept of a memcache has been generalized to that of a "global cache" +and defined by the `GlobalCache` interface, which is an abstract base class. +NDB provides a single concrete implementation of `GlobalCache`, `RedisCache`, +which uses Redis. + +In order to enable the global cache, a `GlobalCache` instance must be passed +into the context. The Bootstrapping example can be amended as follows: + +``` +from google.cloud import ndb + +# Assume GOOGLE_APPLICATION_CREDENTIALS is set in environment. +client = ndb.Client() + +# Assume REDIS_CACHE_URL is set in environment (or not). +# If left unset, this will return `None`, which effectively allows you to turn +# global cache on or off using the environment. +global_cache = ndb.RedisCache().from_environment() + +with client.context(global_cache=global_cache) as context: + do_stuff_with_ndb() +``` + +`context.Context` had a number of methods that were direct pass-throughs to GAE +Memcache. These are no longer implemented. The methods of `context.Context` +that are affected are: `memcache_add`, `memcache_cas`, `memcache_decr`, +`memcache_delete`, `memcache_get`, `memcache_gets`, `memcache_incr`, +`memcache_replace`, `memcache_set`. + ## Differences (between old and new implementations) - The "standard" exceptions from App Engine are no longer available. Instead, @@ -174,6 +207,9 @@ with context as client.context(): - The `max` argument to `Model.allocate_ids` and `Model.allocate_ids_async` is no longer supported. The Google Datastore API does not support setting a maximum ID, a feature that GAE Datastore presumably had. +- `model.get_indexes()` and `model.get_indexes_async()` are no longer + implemented, as the support in Datastore for these functions has disappeared + from GAE to GCP. ## Privatization @@ -189,8 +225,41 @@ facing, private API: and is no longer among top level exports. - `tasklets.MultiFuture` has been renamed to `tasklets._MultiFuture`, removed from top level exports, and has a much simpler interface. -- `Query.run_to_queue` is no longer implemented. Appears to be aimed at - internal usage, despite being nominally public. + +These options classes appear not to have been used directly by users and are +not implemented—public facing API used keyword arguments instead, which are +still supported: + +- `ContextOptions` +- `TransactionOptions` + +The following pieces appear to have been only used internally and are no longer +implemented due to the features they were used for having been refactored: + +- `Query.run_to_queue` +- `tasklets.add_flow_exception` +- `tasklets.make_context` +- `tasklets.make_default_context` +- `tasklets.QueueFuture` +- `tasklets.ReducingFuture` +- `tasklets.SerialQueueFuture` +- `tasklets.set_context` + +A number of functions in the `utils` package appear to have only been used +internally and have been made obsolete either by API changes, internal +refactoring, or new features of Python 3, and are no longer implemented: + +- `utils.code_info()` +- `utils.decorator()` +- `utils.frame_info()` +- `utils.func_info()` +- `utils.gen_info()` +- `utils.get_stack()` +- `utils.logging_debug()` +- `utils.positional()` +- `utils.tweak_logging()` +- `utils.wrapping()` +- `utils.threading_local()` ## Bare Metal diff --git a/src/google/cloud/ndb/__init__.py b/src/google/cloud/ndb/__init__.py index 4c839eb8..f6516581 100644 --- a/src/google/cloud/ndb/__init__.py +++ b/src/google/cloud/ndb/__init__.py @@ -76,6 +76,7 @@ "put_multi", "put_multi_async", "ReadonlyPropertyError", + "RedisCache", "Rollback", "StringProperty", "StructuredProperty", @@ -137,6 +138,7 @@ from google.cloud.ndb._datastore_query import Cursor from google.cloud.ndb._datastore_query import QueryIterator from google.cloud.ndb.global_cache import GlobalCache +from google.cloud.ndb.global_cache import RedisCache from google.cloud.ndb.key import Key from google.cloud.ndb.model import BlobKey from google.cloud.ndb.model import BlobKeyProperty diff --git a/src/google/cloud/ndb/context.py b/src/google/cloud/ndb/context.py index 0e406b17..0bb8a42c 100644 --- a/src/google/cloud/ndb/context.py +++ b/src/google/cloud/ndb/context.py @@ -513,14 +513,14 @@ class ContextOptions: __slots__ = () def __init__(self, *args, **kwargs): - raise NotImplementedError + raise exceptions.NoLongerImplementedError() class TransactionOptions: __slots__ = () def __init__(self, *args, **kwargs): - raise NotImplementedError + raise exceptions.NoLongerImplementedError() class AutoBatcher: diff --git a/src/google/cloud/ndb/model.py b/src/google/cloud/ndb/model.py index 57b1c7a8..6895ecc6 100644 --- a/src/google/cloud/ndb/model.py +++ b/src/google/cloud/ndb/model.py @@ -1869,6 +1869,22 @@ def _deserialize(self, entity, p, unused_depth=1): """ raise exceptions.NoLongerImplementedError() + def _db_set_value(self, v, unused_p, value): + """Helper for :meth:`_serialize`. + + Raises: + NotImplementedError: Always. No longer implemented. + """ + raise exceptions.NoLongerImplementedError() + + def _db_get_value(self, v, unused_p): + """Helper for :meth:`_deserialize`. + + Raises: + NotImplementedError: Always. This method is deprecated. + """ + raise exceptions.NoLongerImplementedError() + def _prepare_for_put(self, entity): """Allow this property to define a pre-put hook. @@ -2082,22 +2098,6 @@ def _validate(self, value): ) return value - def _db_set_value(self, v, unused_p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class IntegerProperty(Property): """A property that contains values of type integer. @@ -2131,22 +2131,6 @@ def _validate(self, value): ) return int(value) - def _db_set_value(self, v, unused_p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class FloatProperty(Property): """A property that contains values of type float. @@ -2181,22 +2165,6 @@ def _validate(self, value): ) return float(value) - def _db_set_value(self, v, unused_p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class _CompressedValue: """A marker object wrapping compressed values. @@ -2368,14 +2336,6 @@ def _from_base_type(self, value): if isinstance(value, _CompressedValue): return zlib.decompress(value.z_val) - def _db_set_value(self, v, unused_p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - def _db_set_compressed_meaning(self, p): """Helper for :meth:`_db_set_value`. @@ -2392,14 +2352,6 @@ def _db_set_uncompressed_meaning(self, p): """ raise exceptions.NoLongerImplementedError() - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class TextProperty(Property): """An unindexed property that contains UTF-8 encoded text values. @@ -2593,22 +2545,6 @@ def _validate(self, value): "Expected GeoPt, got {!r}".format(value) ) - def _db_set_value(self, v, p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class PickleProperty(BlobProperty): """A property that contains values that are pickle-able. @@ -3088,22 +3024,6 @@ def _prepare_for_put(self, entity): entity (Model): An entity with values. """ - def _db_set_value(self, v, p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class KeyProperty(Property): """A property that contains :class:`.Key` values. @@ -3323,22 +3243,6 @@ def _validate(self, value): "{!r}".format(self._kind, value) ) - def _db_set_value(self, v, unused_p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - def _to_base_type(self, value): """Convert a value to the "base" value type for this property. @@ -3393,22 +3297,6 @@ def _validate(self, value): "Expected BlobKey, got {!r}".format(value) ) - def _db_set_value(self, v, p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class DateTimeProperty(Property): """A property that contains :class:`~datetime.datetime` values. @@ -3545,22 +3433,6 @@ def _prepare_for_put(self, entity): value = self._now() self._store_value(entity, value) - def _db_set_value(self, v, p, value): - """Helper for :meth:`_serialize`. - - Raises: - NotImplementedError: Always. No longer implemented. - """ - raise exceptions.NoLongerImplementedError() - - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class DateProperty(DateTimeProperty): """A property that contains :class:`~datetime.date` values. @@ -4072,22 +3944,6 @@ def _validate(self, value): % (self._name, _MAX_STRING_LENGTH) ) - def _db_get_value(self, v, unused_p): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - - def _db_set_value(self, v, p, value): - """Helper for :meth:`_deserialize`. - - Raises: - NotImplementedError: Always. This method is deprecated. - """ - raise exceptions.NoLongerImplementedError() - class ComputedProperty(GenericProperty): """A Property whose value is determined by a user-supplied function.