2012-03-20 151 views
5

與NDB,並就您需要使用類似語法查詢使用過濾器的新的查詢類:NDB查詢過濾

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

我怎樣才能在模型上查詢在不知道提前查詢哪些屬性?

與「舊」的方式,我曾與鍵和值來查詢字典和環繞在鍵和值:

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) 

我怎麼能與NDB實現這一目標?

回答

13

如果它是在Expando模型,或者如果你不在乎驗證屬性名稱,你可以做到這一點很容易地使用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) 

另外,如果你只是想找到一個現有的屬性(在模型中定義的子類),你可以使用_properties類屬性,如

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

甚至使用GETATTR()從類得到它:

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

不同的是,GETATTR()使用該屬性的「巨蟒」的名字,而_properties被索引的「數據存儲「屬性的名稱。這些區別僅在於當地產宣佈與像

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

這裏的Python名是foo,但數據存儲的名稱是吧。

+0

謝謝。甚至不知道我爲什麼不考慮這個... – aschmid00 2012-03-21 17:50:09

+0

這允許動態屬性。有沒有辦法允許動態運營商以及如< and >? – 2014-08-17 15:40:34

+1

好的,在上面的問題得到了答案:http:// stackoverflow。COM /問題/ 8766150 /如何到創建-A-查詢的匹配密鑰。基本上,使用ndb.query.FilterNode(「name」,「=」,value)來構造過濾器 – 2014-08-17 16:02:48

0

你仍然可以做到這一點用字典 - 鍵只是需要模特屬性而不是字符串,像這樣:

kwargs = {MyModel.title : 'mytitle', 
      MyModel.age : 34 } 
q = MyModel.query() 
for prop, value in kwargs.items(): 
    q = q.filter(prop == value) 
+0

我相信這不是100%正確的:[NDB查詢對象是不可變的](http://code.google.com/appengine/docs/python/ndb/queries.html#filter_by_prop)。所以,你的代碼中的最後一行應該是這樣的:「q = q.filter(prop == value)」 – alex 2012-03-21 09:47:19

+0

這不完全是我所需要的。我只有財產標籤作爲一個字符串。所以沒有MyModel.title,但只有'標題'。有沒有辦法通過字符串獲取模型屬性? – aschmid00 2012-03-21 11:48:04

+0

@alex糟糕,這是從數據庫的變化,我不知何故錯過了。我會解決我的答案。 – 2012-03-22 09:07:50