2012-11-13 171 views
2

我使用NDB和稱爲MBObject的Expando模型,因爲我無動態創建對象並且沒有固定方案。我從字典中創建對象:GAE Expando動態設置屬性類型

dic = {"groupName" : "my group", 
     "members" : [{"memberId" : "1"}, {"memberId" : "2"}]} 

所以我想要做的就是創建一個具有稱爲成員財產,其中的成員是MBObjects的LocalStructuredProperty一組對象。 (所有的對象都是MBObject的,ndb.Expando的子類)

然而,似乎沒有要動態指定第二部分的方式,我得到錯誤:

def config_obj_from_dic(dictionary): 
    object = MBObject() 
    for key, value in dictionary.iteritems(): 
     if isinstance(value, list): 
      objects = list() 
      for dic in value: 
       objects.append(config_obj_from_dic(dic)) 
      value = objects 
     setattr(object, key, value) 
    return object 

所以基本上我最終得到了一個成員列表,並嘗試將其設置爲對象的屬性,並希望它自動實現我想要重複的LocalStructuredProperty。所以很明顯,我看到問題出在哪裏,它本身不夠聰明。問題是,我將如何處理它?

如果它不會與LocalStructuredProperty一起工作,那麼我也可以使用ndb.JsonProperty,但它仍然是同樣的問題:我如何動態地告訴它,我希望這是一個屬性某種類型?

TL;博士:如果我有在Expando模型,和我做setattr(object, key, a_list),在這裏我設置一個屬性的列表,我怎麼可以讓它知道我想要一個LocalStructuredPropertyJsonProperty,因爲現在它不不知道該如何處理該清單。

回答

2

NDB expando模型使用GenericProperty來設置數據,它只支持以下類型:int,long,float,bool,str,unicode,datetime,key,BlobKey,GeoPt,User,None。

要解決此問題:如果您知道members的所有屬性和名稱,則可以使用具有預定義屬性(文檔中描述)的expando模型作爲LocalStructuredProperty。但是,如果您不知道這一點(因爲您正在使用expando,這是有意義的),那麼最好的選擇可能是將這些成員手動序列化爲JSON並將它們作爲字符串保存在expando屬性中。

2

此問題可能是realted:http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=216

的修補程序將在應用服務引擎SDK的下一個版本。

def test_expando_in_expando_with_lists(self): 
     """Passes""" 
     class B(ndb.Expando): 
      pass 
     class A(ndb.Expando): 
      pass 
     a = A(a1 = [B(b1 = [0,1,2,3]),B(b2='b2test')]) 
     new_a = A(**a.to_dict()) 
     self.assertEqual(a, new_a) 

我會看看的a.to_dict()在上面的例子中的結構和驗證如何字典:看上去你會先儲存Expando模型(從問題頁面所)內爲Expando模型做到這一點對象看起來與你自己相比。此外,我相信這將使StructuredProperty,而不是LocalStructuredProperty。

如果您可以預先定義屬性類型,則此問題修復了類似的錯誤:http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=207