【问题标题】:Unexpected behavior of ndb Structured Propertyndb 结构化属性的意外行为
【发布时间】:2019-04-27 20:45:14
【问题描述】:

我在我的应用程序中使用 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

问题: 我在资源类中有一个函数,它格式化/序列化从数据库中提取的数据。它看起来像这样:

    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"Test 1", 'external_group_id': 5000}],'owner': 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)

这里,profile模型的序列化函数显示结果为:

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

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

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

我无法理解为什么access_token 显示为一个数组以及为什么groups_ids 是一个数组数组。

谁能帮我理解 ndb 结构化属性的这种行为?特别是我上面解释的情况。

【问题讨论】:

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


    【解决方案1】:

    这里有两个问题:

    关于简介模型

    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,而不是其包含的每个字符串。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 2019-05-04
      • 1970-01-01
      • 2018-11-29
      • 2011-07-04
      相关资源
      最近更新 更多