0
votes

I have an ndb model:

class MyModel(ndb.Model):

  foo = ndb.KeyProperty(repeated=True)
  bar = ndb.KeyProperty(repeated=True)
  # This doesn't work
  baz = ndb.ComputedProperty(lambda self: self.foo + self.bar, repeated=True)

I want to query for a key that is neither in foo nor in bar:

query = MyModel.query().filter(MyModel.foo != my_key).filter(MyModel.bar != my_key)

However, that doesn't work because you can only have one inequality filter.

As such, I added the computed property, baz, so that I could just query for MyModel.baz != my_key. However, that doesn't work either. If I left off the repeated=True part of it, then it raises an exception whenever I put the model because non-repeated properties can't be lists.

When baz is a repeated property, it fails with ComputedPropertyError: Cannot assign to a ComputedProperty. It always fails with this error even if I simplify the lambda to something like lambda self: [1, 2] and even if I do a put immediately after getting the value (without changing anything about it).

I could just use a regular property with a pre put hook:

baz2 = ndb.KeyProperty(repeated=True)

def _pre_put_hook(self):
  self.baz2 = self.foo + self.bar

but it seems like I should just be able to use a ComputedProperty.

Why can't I have a repeated ComputedProperty? Is there a better way to do what I want to do?

Thanks!

1

1 Answers

0
votes

I discovered the issue. Apparently, I was overwriting put and using put(**my_model._to_dict()), which had the effect of trying to assign something to the computed property.

In other words, everything works as expected, and unless you're doing something complicated, repeated computed properties work fine.