Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test for unset repeated properties in NDB?

How to I test for unset repeated properties in NDB after entity has been set?

The only reference I can find says:

Querying for a value of None on a repeated property has undefined behavior; don't do that.

like image 554
wag2639 Avatar asked Dec 18 '12 08:12

wag2639


1 Answers

If you never add anything to the contents of the list in a repeated property, no value will be sent, and the property will show up as <missing> not as <null>

According to the App Engine documentation on Queries and Indexes, there is a distinction between entities that have no value for a property, and those that have a null value for it; and

Entities Without a Filtered Property Are Never Returned by a Query.

So it is not possible to write a query for these old records.

See the rest of the answer quoted above at
AppEngine: Query datastore for records with <missing> value

If you want to be able to query for such things, you should enforce this in your data model. For example you could have a ndb.ComputedProperty which is a boolean corresponding to whether or not the corresponding list has length zero, e.g.

class MyModel(ndb.Model):
  my_repeat = ndb.StringProperty(repeated=True)
  sentinel = ndb.ComputedProperty(lambda self: len(self.my_repeat) == 0)

and to query for these missing values, you could use

MyModel.query(MyModel.sentinel == True)

If you have an existing set of such objects in your datastore, you can run a one-time mapreduce over them and simply retrieve each entity using the updated model definition and then put each back into the datastore. This will keep all existing properties the same and update with the sentinel value.

like image 129
bossylobster Avatar answered Sep 23 '22 17:09

bossylobster