ndb结构化属性的意外行为

时间:2018-11-26 08:26:11

标签: python-2.7 google-app-engine google-cloud-datastore app-engine-ndb

我在我的应用程序中使用了ndb结构化属性。这些模型如下所示:

资源外部集成:

class ResourceExternalIntegration(ndb.Model):
  integration_type = ndb.StringProperty()
  external_resource_type = ndb.StringProperty()
  external_resource_id = ndb.IntegerProperty()
  external_group_id = ndb.IntegerProperty()
  external_resource_name = ndb.StringProperty()

资源模型:

class Resource(ndb.Model):
  owner = ndb.IntegerProperty()
  name = ndb.StringProperty()
  type = ndb.StringProperty()
  external_integrations = ndb.StructuredProperty(ResourceExternalIntegration, repeated=True)

请注意,我的结构化属性为repeated=True

问题: 我在Resource类中有一个函数,用于格式化/序列化从DB中提取的数据。看起来像这样:

    def serialize(self):

    external_integrations_list = []
    if self.external_integrations:
        for external_integration in self.external_integrations:
            external_integration_dict = dict()
            external_integration_dict['integration_type'] = external_integration.integration_type,
            external_integration_dict['external_resource_type'] = external_integration.external_resource_type,
            external_integration_dict['external_resource_id'] = external_integration.external_resource_id
            external_integration_dict['external_group_id'] = external_integration.external_group_id
            external_integration_dict['external_resource_name'] = external_integration.external_resource_name
            external_integrations_list.append(external_integration_dict)

    resource_data.update(dict(
        owner=self.owner,
        name=self.name,
        type=self.type,
        external_integrations=external_integrations_list

    ))
    return resource_data

现在,在resource_data中,属性external_integrations应该是一个数组,其中的每个元素也应该是一个数组,即external_resource_idexternal_resource_type等也应该是数组。这是因为结构化属性被设置为repeated=True。但是,resource_data不包含此预期结果。看起来像:

{'name':u'Scissors lift','type':u'Scissors','external_integrations':[{'external_resource_type':(u'FLEET',),'integration_type':(u'ABC' ,),'external_resource_id':212017856321402L,'external_resource_name':u“测试1”,'external_group_id':5000}],'所有者':5629490125014563L}

而且,在浏览器上看起来像这样:

external_group_id: 5000
external_resource_id: 212017856321402
external_resource_name: "Test 1"
external_resource_type: ["FLEET"]
integration_type: ["ABC"]

external_group_idexternal_resource_idexternal_resource_name不会显示为数组,但是它们应作为数组出现。

我还有另一个模型,其中结构化属性不以repeated=True的形式存在。看起来像:

外部集成

class ExternalIntegration(ndb.Model):
  access_token = ndb.StringProperty()
  group_ids = ndb.IntegerProperty(repeated=True)

个人资料

class profile(ndb.Model):
  name = ndb.StringProperty()
  integration_info = ndb.StructuredProperty(ExternalIntegration)

在这里,概要文件模型的序列化功能显示为:

{'integration_info':{'group_ids':([5000],),'access_token':(u'blahblahblahblah',)},``名称:'Test'}

而且,在浏览器上,结果如下:

access_token: ["blahblahblahblah"]
group_ids: [[5000]]

我无法理解为什么access_token是数组,为什么groups_ids是数组数组。

有人可以帮助我了解ndb结构化属性的这种行为吗?具体来说,我在上面已经解释过了。

1 个答案:

答案 0 :(得分:0)

这里有两个问题:

关于个人资料模型

integration_info包含在ExternalIntegration类中定义的两个元素。它被保存为包含两个元素的字典:access_tokengroup_idsgroup_idsrepeated=Truewhich takes a list of values of the underlying type定义,该列表创建一个列表。总结一下:

  1. access_token显示为字符串。
  2. group_ids显示为列表,因为repeated设置为True

关于资源模型

  1. external_integrations出现在列表中,因为您定义了repeated=True
  2. 列表中只有一个元素,因为整个字典是通过单个操作附加的,而不是每个元素的附加。
  3. external_group_idexternal_resource_idexternal_resource_name不会显示为数组,因为它们不是用repeated=True定义的。该定义在上一级应用于external_integrations,而不应用于其包含的每个字符串。

尝试重新定义应该重复的元素和不应该重复的元素。