首页 > 解决方案 > 从不同 API 获取的 Datastore Entity 类型之间的差异

问题描述

以下是使用 GCP 数据存储区实体的 2 种方法:

选项 1 - gcloud 客户端库

from google.cloud import datastore
client = datastore.Client()
...
key = datastore.key.Key(kind, id, project=project_id)
entity = client.get(key)

上面的类型entity<class 'google.cloud.datastore.entity.Entity'>,内容看起来像

<Entity('DemoClass', 1234567890123) {'prop1': 'xxx', 'prop2': 'yyy', ...}>

选项 2 - REST API

使用 Rest API 执行 Datastore 查询的响应是QueryResultBatch,其中包含EntityResult列表,并且在EntityResult中有一个Entity对象。这个实体对象的类型是<class 'dict'>,它看起来像这样:

{
  "key": {
    {'partitionId': {
       'projectId': 'test_project'
      }, 
     'path': [{'kind': 'DemoClass', 'id': '1234567890123'}]
    }
  },
  "properties": {
    string: {
      object(Value)
    },
    ...
  },
}

问题

是否有任何“内置”方式来回转换它们?当我DatastoreHook在 Airflow 中使用时,因为它基于 Rest API,所以我得到的是Entity dict,我当然可以构造 adatastore.key.Key并重新获取 a google.cloud.datastore.entity.Entity,但我想知道是否有更好、更少浪费的方法正在做。

标签: google-cloud-datastoreairflowgcloud

解决方案


的格式Option 2 - REST API看起来像entity_pb2.Entity格式

它看起来google.cloud.datastore有这个功能:

google.cloud.datastore.helpers.entity_from_protobuf

https://googleapis.dev/python/datastore/latest/helpers.html#google.cloud.datastore.helpers.entity_from_protobuf

所以最后一块拼图实际上是将响应Option 2 - REST API转换为实际的实例entity_pb2.Entity

还有这个面向 entity_pb2 https://github.com/GoogleCloudPlatform/google-cloud-datastore/blob/master/python/googledatastore/helper.py的其他帮助程序库

可能有一个现有的函数可以做到这一点,但这样的事情应该可以解决问题:

from google.cloud.proto.datastore.v1 import entity_pb2
from googledatastore import helper

def parse_query_result(result):    
    """Transform a single query result into a `google.cloud.datastore.entity.Entity`"""

    entity = entity_pb2.Entity()
    for path_element in result['key']:
        helper.add_key_path(entity.key, path_element['kind'], path_element['id'])

    for key, value_obj in result['properties'].iteritems():
        name = value_obj.keys()[0]
        value = value_obj[name]
        helper.set_property(entity.properties, name, value)

    return google.cloud.datastore.helpers.entity_from_protobuf(entity)

推荐阅读