2012-11-29 33 views
2

嗨即時試圖找出如何構建我的查詢以下情況NDB在查詢GenericProperty重複Expando的StructuredProperty

首先我有一個模型中定義

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() 

,然後查詢的東西..到目前爲止,我已經試過

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") 

,沒有這些作品的。這應該是完全可能的,因爲數據存儲中的屬性名稱是

variants.dynamic = ["a", ] 

謝謝您的幫助

+0

你試過'Item.query(ndb.GenericProperty('variants.dynamic')=='a')'? –

+0

試圖實例化'ndb.GenericProperty('variants.dynamic')'產生'ValueError:Name'variants.dynamic'不能包含來自'ndb/model.py'第765行的句點字符。看起來這應該是一個特性請求。 – bossylobster

回答

4

它使用很容易GQL:

Item.gql("WHERE variants.dynamic = 'a'").fetch() 

而且這個工程:

s = StringProperty() 
s._name = 'variants.dynamic') 
Item.query(s == 'a').fetch() 

請做文件功能要求;然而這將是一個平衡的行爲。你想用什麼語法?

UPDATE:

同樣的事情可與GenericProperty(),或任何其他屬性的子類。

GenericProperty('variants。動態「)是被禁止的是阻止人們這樣做的黑客就像這樣:

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

這會混淆序列化和反序列化的代碼。

也許我們可以爲屬性添加一個標誌,以跳過此檢查,但不允許在模型定義中使用該屬性(它只允許在查詢中使用該屬性)。

或許我們可以使這項工作(我認爲這將是很難雖然):

Item.query(Item.variants.dynamic == 'a').fetch() 

(僅當變種是在Expando)。

+0

Dang完全忘記了gql,這當然是一個簡單的解決方案。我認爲正確的語法是GenericProperty(「variants.dynamic」),因爲target屬性畢竟是GenericProperty。你的例子可以用於任何類型或只是字符串嗎? –

+0

這也適用於GenericProperty。 –

+0

最後一個解決方案dosnt爲我工作,因爲我必須從字符串引用屬性。 –

1

你可以用一點神奇的做到這一點。

簡短的回答

variants_dynamic_property = ndb.GenericProperty() 
variants_dynamic_property._name = 'variants.dynamic' 
q = Item.query(variants_dynamic_property == 'a') 

長的答案

既然你要查詢一個GenericProperty,你需要創建一個爲docs狀態,例如:

FlexEmployee.query(ndb.GenericProperty('location') == 'SF') 

同樣,當查詢StucturedProperty,在docs狀態,你可以使用屬性的屬性,如:

Contact.query(Contact.address.city == 'Amsterdam') 

所以結合這些,就需要

Item.query(ndb.GenericProperty('variants.dynamic') == 'a') 

而是試圖通過ndb.GenericProperty('variants.dynamic')結果構建財產以下異常:

File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/utils.py", line 136, in positional_wrapper 
    return wrapped(*args, **kwds) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 2366, in __init__ 
    super(GenericProperty, self).__init__(name=name, **kwds) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/utils.py", line 136, in positional_wrapper 
    return wrapped(*args, **kwds) 
    File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 765, in __init__ 
    raise ValueError('Name %r cannot contain period characters' % (name,)) 
ValueError: Name 'variants.dynamic' cannot contain period characters 

但是你可以通過使用構造不帶屬性的名稱,然後設置解決這個問題事後名稱:

variants_dynamic_property = ndb.GenericProperty() 
variants_dynamic_property._name = 'variants.dynamic' 
+0

不等於Item.query(ndb.query.FilterNode(「variants。%s」%dynamic,「=」,「a」))?你有沒有測試過,如果這真的有效? –

+0

是的,它確實有效,但是在寫完之後我痛苦地發現了這些,而不是「重複」的屬性。我仍在努力。我不確定這兩者是否相同,但他們很可能。 – bossylobster

0

hackish的解決方案

一個臨時解決方案:使用ComputedProperty通過查詢 - 在我們的例子:

(加入以下模型定義)

computed_prop = ndb.ComputedProperty(lambda self: self.repeating_prop[0].sub_prop if self.repeating_prop else None)