-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: fix bug with repeated structured properties with Expando values (#…
…671) In the legacy data format, the dotted properties stored in Datastore were not properly padded for missing values. Fixes #669
- Loading branch information
Chris Rossi
authored
Jun 25, 2021
1 parent
f95efa3
commit 882dff0
Showing
2 changed files
with
62 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -696,26 +696,29 @@ def _entity_from_protobuf(protobuf): | |
return _entity_from_ds_entity(ds_entity) | ||
|
||
|
||
def _properties_of(entity): | ||
"""Get the model properties for an entity. | ||
def _properties_of(*entities): | ||
"""Get the model properties for one or more entities. | ||
After collecting any properties local to the given entity, will traverse the | ||
entity's MRO (class hierarchy) up from the entity's class through all of its | ||
ancestors, collecting an ``Property`` instances defined for those classes. | ||
After collecting any properties local to the given entities, will traverse the | ||
entities' MRO (class hierarchy) up from the entities' class through all of its | ||
ancestors, collecting any ``Property`` instances defined for those classes. | ||
Args: | ||
entity (model.Model): The entity to get properties for. | ||
entities (Tuple[model.Model]): The entities to get properties for. All entities | ||
are expected to be of the same class. | ||
Returns: | ||
Iterator[Property]: Iterator over the entity's properties. | ||
Iterator[Property]: Iterator over the entities' properties. | ||
""" | ||
seen = set() | ||
|
||
for level in (entity,) + tuple(type(entity).mro()): | ||
entity_type = type(entities[0]) # assume all entities are same type | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
josecols
|
||
for level in entities + tuple(entity_type.mro()): | ||
if not hasattr(level, "_properties"): | ||
continue | ||
|
||
for prop in level._properties.values(): | ||
level_properties = getattr(level, "_properties", {}) | ||
for prop in level_properties.values(): | ||
if ( | ||
not isinstance(prop, Property) | ||
or isinstance(prop, ModelKey) | ||
|
@@ -4299,6 +4302,8 @@ def _to_datastore(self, entity, data, prefix="", repeated=False): | |
if not self._repeated: | ||
values = (values,) | ||
|
||
props = tuple(_properties_of(*values)) | ||
|
||
for value in values: | ||
if value is None: | ||
keys.extend( | ||
|
@@ -4308,7 +4313,7 @@ def _to_datastore(self, entity, data, prefix="", repeated=False): | |
) | ||
continue | ||
|
||
for prop in _properties_of(value): | ||
for prop in props: | ||
keys.extend( | ||
prop._to_datastore( | ||
value, data, prefix=next_prefix, repeated=next_repeated | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This line of code breaks the case where the entities is an empty list, i.e., the model's repeated structured property is set to empty list.