Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NDB query filtering by property (string)

with ndb and the new query class to to use filter on a query you need to use the syntax like:

qry = MyModel.query(MyModel.title == 'title')

how can i query on a model without knowing in advance which properties i have to query on?

with the 'old' way i had a dictionary with keys and values to query on and looped over keys and values:

kwargs = {'title' : 'mytitle', 
          'age'   : 34 }

q = MyModel.all()

for kw, vals in kwargs.items():
    if not isinstance(vals, (list, tuple)):
        vals = (vals,)
    for v in vals:
        q.filter('%s =' % kw, v)

how could i achieve this with ndb?

like image 466
aschmid00 Avatar asked Mar 20 '12 22:03

aschmid00


1 Answers

If it's an Expando model, or if you don't care validating the property name, you can do this easily using GenericProperty:

kwargs = {'title' : 'mytitle', 
          'age'   : 34 }

q = MyModel.query()

for kw, vals in kwargs.items():
    if not isinstance(vals, (list, tuple)):
        vals = (vals,)
    for v in vals:
        q = q.filter(ndb.GenericProperty(kw) == v)

Alternatively, if you just want to find an existing property (defined in your Model subclass) by name, you could use the _properties class attribute, e.g.

        q = q.filter(MyModel._properties[kw] == v)

or even use getattr() to get it from the class:

        q = q.filter(getattr(MyModel, kw) == v)

The difference is that getattr() uses the "Python" name of the property while _properties is indexed by the "datastore" name of the property. These only differ when the property was declared with something like

class MyModel(ndb.Model):
  foo = StringProperty('bar')

Here the Python name is foo but the datastore name is bar.

like image 124
Guido van Rossum Avatar answered Sep 30 '22 17:09

Guido van Rossum