Hey guys im trying to figure out how to structure my query for the following case
First i have a model defined
class Variant(ndb.Expando):
test = ndb.StringProperty()
class Item(ndb.Model):
test2 = ndb.StringProperty()
variants = ndb.StructuredProperty(Variant, repeated=True)
variant = Variant(test="test", dynamic="a")
item = Item(test2="test", variants=[variant, ])
item.put()
and then for the query stuff.. So far i’ve tried
dynamic = "dynamic"
Item.query(ndb.GenericProperty("variants.%s" % dynamic) == "a")
Item.query(Item._properties["variants.%s" % dynamic] == "a")
Item.query(getattr(Item.variants, dynamic) == "a")
Item.query(getattr(Item, "variants.%s" % dynamic) == "a")
Item.query(ndb.query.FilterNode("variants.%s" % dynamic, "=", "a"))
generic_prop = ndb.GenericProperty()
generic_prop._name = "variants.%s" % dynamic
Item.query(generic_prop == "a")
and none of these works.. This should be perfectly possible since the property name in the datastore is
variants.dynamic = ["a", ]
Thank you for your help
It’s easy using GQL:
Also this works:
Please do file a feature request; however it’s going to be a balancing act. What syntax would you like to use?
UPDATE:
The same thing works with GenericProperty(), or any other Property subclass.
The reason that GenericProperty(‘variants.dynamic’) is forbidden is to prevent people from doing hacks like this:
which will confuse the serialization and deserialization code.
Maybe we can add a flag to Property that skips this check but then disallows using the property in a model definition (it would only allow it in a query).
Or maybe we can make this work (I think this would be hard though):
(only if variants is an Expando).