GAE Expando动态设置属性类型

时间:2012-11-13 23:56:21

标签: python google-app-engine

我正在使用NDB和名为MBObject的Expando模型,因为我在没有固定方案的情况下动态创建对象。我从字典创建对象:

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

所以我想要做的是创建一个具有名为members的属性的组对象,其中成员是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。所以很明显我看到问题出在哪里,它本身就不够聪明。问题是,我将如何处理它?<​​/ p>

如果它不适用于LocalStructuredProperty,那么我也可以使用ndb.JsonProperty,但它仍然是同样的问题:我如何动态告诉它我希望它是一个属性某种类型?

tl; dr:如果我有一个Expando模型,并且我setattr(object, key, a_list),我将属性设置为列表,如何让它知道我想要一个{ {1}}或LocalStructuredProperty,因为现在它不知道如何处理该列表。

2 个答案:

答案 0 :(得分:2)

NDB expando模型使用GenericProperty来设置数据,它只支持以下类型:int,long,float,bool,str,unicode,datetime,Key,BlobKey,GeoPt,User,None。

要解决此问题:如果您知道members的所有属性和名称,则可以将具有预定义属性(在文档中描述)的expando模型用作LocalStructuredProperty。但是,如果你不知道这个(因为你使用expando会有意义),那么最好的选择可能是手动将这些成员序列化为JSON并将它们作为字符串保存在expando属性中。

答案 1 :(得分:2)

可能会出现此问题:http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=216

修复程序将在AppEngine SDK的下一个版本中。看起来你首先在Expando模型中存储Expando模型(取自问题页面):

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()的结构,并验证字典对象与您自己的对比情况。此外,我相信这将构成StructuredProperty,而不是LocalStructuredProperty。

如果您可以预先定义属性类型,则此问题修复了类似的错误:http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=207

相关问题