2

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

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

所以我想做的是创建一个组对象,它有一个名为 members 的属性,其中 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。所以很明显我看到了问题所在,它不够聪明,无法自己处理。问题是,我将如何让它处理它?

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

tl;dr:如果我有一个 Expando 模型,并且我有setattr(object, key, a_list),我将一个属性设置为一个列表,我怎样才能让它知道我想要 aLocalStructuredProperty或 a JsonProperty,因为现在它不知道如何处理该列表.

4

2 回答 2

2

The NDB expando model uses GenericProperty to set data, which only supports the following types: int, long, float, bool, str, unicode, datetime, Key, BlobKey, GeoPt, User, None.

To solve this problem: if you know all the properties and names of members, then you can use an expando model with predefined properties (described in the docs) as LocalStructuredProperty. However, if you don't know this (which would make sense since you're using expando), then the best options may be to serialize these members to JSON manually and save them in an expando property as a string.

于 2012-11-14T10:36:51.493 回答
2

This issue may be realted: http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=216

The fix will be in the next release of the AppEngine SDK. Looks like you'd do this by first storing Expando models inside the Expando model (taken from the issues page):

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)

I would take a look at the structure of a.to_dict() in the example above and verify how the dictionary object looks in comparison to your own. Also, I believe this will make a StructuredProperty, not a LocalStructuredProperty.

If you can pre-define the property type, this issue fixed a similar bug: http://code.google.com/p/appengine-ndb-experiment/issues/detail?id=207

于 2012-11-15T16:52:08.357 回答