Различия между типами сущностей Datastore, полученными из разных API - PullRequest
1 голос
/ 17 октября 2019

есть 2 способа работы с объектами хранилища данных GCP:

Вариант 1 - клиент gcloud lib

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 является 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 , я, безусловно, могу создать datastore.key.Key и повторно получить, чтобы получить google.cloud.datastore.entity.Entity, но мне интересно, есть ли лучший, менее расточительный способ сделать это.

1 Ответ

1 голос
/ 18 октября 2019

Формат 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)
...