googleapis/python-ndb

A nested LocalStructuredProperty does not save in a way that can be read from Legacy NDB (proposal for a one-line fix included)

DerekDuchesne opened this issue · 0 comments

  1. API: python-ndb
  2. N/A
  3. Python 3.11.4
  4. google-cloud-ndb version: v2.2.2

Description

I have a model that looks like this:

class ChildLocalStructuredProperty(ndb.Model):
    str_field = ndb.StringProperty('s', indexed=False)

class ChildStructuredProperty(ndb.Model):
    local_structured_properties = ndb.LocalStructuredProperty(ChildLocalStructuredProperty, 'lp', repeated=True, indexed=False)

class Parent(ndb.Model):
    structured_property = ndb.StructuredProperty(ChildStructuredProperty, 'sp')

When saving the Parent entity, I found that the resulting properties would be:

[
    'sp.lp', (blobValue not readable by legacy NDB)
    'lp' (Array value readable by legacy NDB, but not prefixed correctly)
]

Possible fix

I traced the issue to _to_datastore() under class LocalStructuredProperty in google/cloud/ndb/model.py line 4497 where it sets data[self._name] = legacy_values:

if context.legacy_data:
    values = self._get_user_value(entity)
    if not self._repeated:
        values = [values]
    legacy_values = []
    for value in values:
        ds_entity = None
        if value is not None:
            ds_entity = _entity_to_ds_entity(value, set_key=self._keep_keys)
        legacy_values.append(ds_entity)
    if not self._repeated:
        legacy_values = legacy_values[0]
    data[self._name] = legacy_values        # <----- HERE

return keys

I believe it should be data[prefix + self._name] so that the legacy value is stored under the right property name including the prefix.

Thanks!