From dab9edf0fc161051eb13c296cbe973b3a16b502d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20=C5=BBy=C5=BAniewski?= Date: Tue, 27 Feb 2024 21:46:58 +0100 Subject: [PATCH] fix: compressed repeated to uncompressed property (#772) --- google/cloud/ndb/model.py | 6 +++++- tests/unit/test_model.py | 31 +++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/google/cloud/ndb/model.py b/google/cloud/ndb/model.py index 42fe044b..224c6deb 100644 --- a/google/cloud/ndb/model.py +++ b/google/cloud/ndb/model.py @@ -2672,7 +2672,11 @@ def _from_datastore(self, ds_entity, value): if self._name in ds_entity._meanings: meaning = ds_entity._meanings[self._name][0] if meaning == _MEANING_COMPRESSED and not self._compressed: - value.b_val = zlib.decompress(value.b_val) + if self._repeated: + for sub_value in value: + sub_value.b_val = zlib.decompress(sub_value.b_val) + else: + value.b_val = zlib.decompress(value.b_val) return value def _db_set_compressed_meaning(self, p): diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py index 6cb0ac90..5e6a11cb 100644 --- a/tests/unit/test_model.py +++ b/tests/unit/test_model.py @@ -1862,11 +1862,12 @@ class ThisKind(model.Model): compressed_value_one = zlib.compress(uncompressed_value_one) uncompressed_value_two = b"xyz" * 1000 compressed_value_two = zlib.compress(uncompressed_value_two) - datastore_entity.update({"foo": [compressed_value_one, compressed_value_two]}) + compressed_value = [compressed_value_one, compressed_value_two] + datastore_entity.update({"foo": compressed_value}) meanings = { "foo": ( model._MEANING_COMPRESSED, - [compressed_value_one, compressed_value_two], + compressed_value, ) } datastore_entity._meanings = meanings @@ -1875,6 +1876,32 @@ class ThisKind(model.Model): ds_entity = model._entity_to_ds_entity(entity) assert ds_entity["foo"] == [compressed_value_one, compressed_value_two] + @staticmethod + @pytest.mark.usefixtures("in_context") + def test__from_datastore_compressed_repeated_to_uncompressed(): + class ThisKind(model.Model): + foo = model.BlobProperty(compressed=False, repeated=True) + + key = datastore.Key("ThisKind", 123, project="testing") + datastore_entity = datastore.Entity(key=key) + uncompressed_value_one = b"abc" * 1000 + compressed_value_one = zlib.compress(uncompressed_value_one) + uncompressed_value_two = b"xyz" * 1000 + compressed_value_two = zlib.compress(uncompressed_value_two) + compressed_value = [compressed_value_one, compressed_value_two] + datastore_entity.update({"foo": compressed_value}) + meanings = { + "foo": ( + model._MEANING_COMPRESSED, + compressed_value, + ) + } + datastore_entity._meanings = meanings + protobuf = helpers.entity_to_protobuf(datastore_entity) + entity = model._entity_from_protobuf(protobuf) + ds_entity = model._entity_to_ds_entity(entity) + assert ds_entity["foo"] == [uncompressed_value_one, uncompressed_value_two] + @staticmethod @pytest.mark.usefixtures("in_context") def test__from_datastore_uncompressed_to_uncompressed():