google-cloud-ndb==2.3.0, Python 3.11.
If I assign a dynamic property on an Expando and put(), the first write sticks. Changing that same property later and put() again looks fine (no error; in-process it even reads as the new value) but a refetch from datastore still has the old number.
Declared properties on the class (e.g. FloatProperty) update correctly. This also worked on the old App Engine ndb.
from google.cloud import ndb
class Item(ndb.Expando):
name = ndb.StringProperty()
# ndb client context already active
ent = Item(name="x")
ent.extra = 2.00
key = ent.put()
ent = key.get()
ent.extra = 9.99
ent.put()
ent = key.get()
print(ent.extra) # 2.00, expected 9.99
Expando.__setattr__ looks like the cause. If the name is already in _properties it calls super().__setattr__. For a class-level Property that hits the descriptor and updates _values. For a dynamic name there is no descriptor on the class, so it lands in __dict__ and put() serializes the stale _values.
Is this expected? I couldn't find it documented. The old runtime always went through _set_value for non-class names.
Opened here because https://github.com/googleapis/python-ndb is archived.
google-cloud-ndb==2.3.0, Python 3.11.If I assign a dynamic property on an Expando and
put(), the first write sticks. Changing that same property later andput()again looks fine (no error; in-process it even reads as the new value) but a refetch from datastore still has the old number.Declared properties on the class (e.g.
FloatProperty) update correctly. This also worked on the old App Engine ndb.Expando.__setattr__looks like the cause. If the name is already in_propertiesit callssuper().__setattr__. For a class-level Property that hits the descriptor and updates_values. For a dynamic name there is no descriptor on the class, so it lands in__dict__andput()serializes the stale_values.Is this expected? I couldn't find it documented. The old runtime always went through
_set_valuefor non-class names.Opened here because https://github.com/googleapis/python-ndb is archived.