diff --git a/datastore/google/cloud/datastore/helpers.py b/datastore/google/cloud/datastore/helpers.py index 964eb2a37204..38c4b0ddfdf6 100644 --- a/datastore/google/cloud/datastore/helpers.py +++ b/datastore/google/cloud/datastore/helpers.py @@ -212,8 +212,6 @@ def entity_to_protobuf(entity): for name, value in entity.items(): value_is_list = isinstance(value, list) - if value_is_list and len(value) == 0: - continue value_pb = _new_value_pb(entity_pb, name) # Set the appropriate value. @@ -453,10 +451,14 @@ def _set_protobuf_value(value_pb, val): entity_pb = entity_to_protobuf(val) value_pb.entity_value.CopyFrom(entity_pb) elif attr == 'array_value': - l_pb = value_pb.array_value.values - for item in val: - i_pb = l_pb.add() - _set_protobuf_value(i_pb, item) + if len(val) == 0: + array_value = entity_pb2.ArrayValue(values=[]) + value_pb.array_value.CopyFrom(array_value) + else: + l_pb = value_pb.array_value.values + for item in val: + i_pb = l_pb.add() + _set_protobuf_value(i_pb, item) elif attr == 'geo_point_value': value_pb.geo_point_value.CopyFrom(val) else: # scalar, just assign diff --git a/datastore/tests/system/test_system.py b/datastore/tests/system/test_system.py index c73b2a80cc17..2a1080b628e5 100644 --- a/datastore/tests/system/test_system.py +++ b/datastore/tests/system/test_system.py @@ -547,3 +547,15 @@ def test_failure_with_contention(self): # transaction. entity_in_txn[contention_prop_name] = u'inside' txn.put(entity_in_txn) + + def test_empty_array_put(self): + local_client = clone_client(Config.CLIENT) + + key = local_client.key('EmptyArray', 1234) + local_client = datastore.Client() + entity = datastore.Entity(key=key) + entity['children'] = [] + local_client.put(entity) + retrieved = local_client.get(entity.key) + + self.assertEqual(entity['children'], retrieved['children']) diff --git a/datastore/tests/unit/test_batch.py b/datastore/tests/unit/test_batch.py index 9b854141e553..4b94b657e9d0 100644 --- a/datastore/tests/unit/test_batch.py +++ b/datastore/tests/unit/test_batch.py @@ -119,7 +119,7 @@ def test_put_entity_w_completed_key(self): 'foo': 'bar', 'baz': 'qux', 'spam': [1, 2, 3], - 'frotz': [], # will be ignored + 'frotz': [], } client = _Client(project) batch = self._make_one(client) @@ -134,7 +134,7 @@ def test_put_entity_w_completed_key(self): self.assertEqual(mutated_entity.key, key._key) prop_dict = dict(_property_tuples(mutated_entity)) - self.assertEqual(len(prop_dict), 3) + self.assertEqual(len(prop_dict), 4) self.assertFalse(prop_dict['foo'].exclude_from_indexes) self.assertTrue(prop_dict['baz'].exclude_from_indexes) self.assertFalse(prop_dict['spam'].exclude_from_indexes) @@ -142,7 +142,7 @@ def test_put_entity_w_completed_key(self): self.assertTrue(spam_values[0].exclude_from_indexes) self.assertTrue(spam_values[1].exclude_from_indexes) self.assertTrue(spam_values[2].exclude_from_indexes) - self.assertFalse('frotz' in prop_dict) + self.assertTrue('frotz' in prop_dict) def test_delete_wrong_status(self): project = 'PROJECT' diff --git a/datastore/tests/unit/test_helpers.py b/datastore/tests/unit/test_helpers.py index 91a693455b7d..f4338812be54 100644 --- a/datastore/tests/unit/test_helpers.py +++ b/datastore/tests/unit/test_helpers.py @@ -294,7 +294,11 @@ def test_with_empty_list(self): entity['foo'] = [] entity_pb = self._call_fut(entity) - self._compare_entity_proto(entity_pb, entity_pb2.Entity()) + expected_pb = entity_pb2.Entity() + prop = expected_pb.properties.get_or_create('foo') + prop.array_value.CopyFrom(entity_pb2.ArrayValue(values=[])) + + self._compare_entity_proto(entity_pb, expected_pb) def test_inverts_to_protobuf(self): from google.cloud.datastore_v1.proto import entity_pb2