Skip to content

Commit e688cd6

Browse files
author
Chris Rossi
authored
fix: allow for legacy repeated structured properties with empty values (#702)
Fixes #694
1 parent 86bf7f5 commit e688cd6

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

packages/google-cloud-ndb/google/cloud/ndb/model.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4302,23 +4302,24 @@ def _to_datastore(self, entity, data, prefix="", repeated=False):
43024302
if not self._repeated:
43034303
values = (values,)
43044304

4305-
props = tuple(_properties_of(*values))
4305+
if values:
4306+
props = tuple(_properties_of(*values))
43064307

4307-
for value in values:
4308-
if value is None:
4309-
keys.extend(
4310-
super(StructuredProperty, self)._to_datastore(
4311-
entity, data, prefix=prefix, repeated=repeated
4308+
for value in values:
4309+
if value is None:
4310+
keys.extend(
4311+
super(StructuredProperty, self)._to_datastore(
4312+
entity, data, prefix=prefix, repeated=repeated
4313+
)
43124314
)
4313-
)
4314-
continue
4315+
continue
43154316

4316-
for prop in props:
4317-
keys.extend(
4318-
prop._to_datastore(
4319-
value, data, prefix=next_prefix, repeated=next_repeated
4317+
for prop in props:
4318+
keys.extend(
4319+
prop._to_datastore(
4320+
value, data, prefix=next_prefix, repeated=next_repeated
4321+
)
43204322
)
4321-
)
43224323

43234324
return set(keys)
43244325

packages/google-cloud-ndb/tests/system/test_crud.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,33 @@ class SomeKind(ndb.Model):
11641164
assert isinstance(retrieved.bar[2], OtherKind)
11651165

11661166

1167+
@pytest.mark.usefixtures("client_context")
1168+
def test_legacy_repeated_structured_property_w_expando_empty(
1169+
ds_client, dispose_of, client_context
1170+
):
1171+
"""Regression test for #669
1172+
1173+
https://github.com/googleapis/python-ndb/issues/669
1174+
"""
1175+
1176+
class OtherKind(ndb.Expando):
1177+
one = ndb.StringProperty()
1178+
1179+
class SomeKind(ndb.Model):
1180+
foo = ndb.IntegerProperty()
1181+
bar = ndb.StructuredProperty(OtherKind, repeated=True)
1182+
1183+
entity = SomeKind(foo=42, bar=[])
1184+
1185+
with client_context.new(legacy_data=True).use():
1186+
key = entity.put()
1187+
dispose_of(key._key)
1188+
1189+
retrieved = key.get()
1190+
assert retrieved.foo == 42
1191+
assert retrieved.bar == []
1192+
1193+
11671194
@pytest.mark.usefixtures("client_context")
11681195
def test_insert_expando(dispose_of):
11691196
class SomeKind(ndb.Expando):

packages/google-cloud-ndb/tests/unit/test_model.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3524,6 +3524,20 @@ class SomeKind(model.Model):
35243524
assert SomeKind.foo._to_datastore(entity, data) == {"foo.bar"}
35253525
assert data == {"foo.bar": ["baz", "boz"]}
35263526

3527+
@staticmethod
3528+
def test__to_datastore_legacy_repeated_empty_value(in_context):
3529+
class SubKind(model.Model):
3530+
bar = model.Property()
3531+
3532+
class SomeKind(model.Model):
3533+
foo = model.StructuredProperty(SubKind, repeated=True)
3534+
3535+
with in_context.new(legacy_data=True).use():
3536+
entity = SomeKind(foo=[])
3537+
data = {}
3538+
assert SomeKind.foo._to_datastore(entity, data) == set()
3539+
assert data == {}
3540+
35273541
@staticmethod
35283542
def test__prepare_for_put():
35293543
class SubKind(model.Model):

0 commit comments

Comments
 (0)