def entity_from_protobuf(pb): """Factory method for creating an entity based on a protobuf. The protobuf should be one returned from the Cloud Datastore Protobuf API. :type pb: :class:`gcloud.datastore._generated.entity_pb2.Entity` :param pb: The Protobuf representing the entity. :rtype: :class:`gcloud.datastore.entity.Entity` :returns: The entity derived from the protobuf. """ key = None if pb.HasField('key'): # Message field (Key) key = key_from_protobuf(pb.key) entity_props = {} entity_meanings = {} exclude_from_indexes = [] for prop_name, value_pb in _property_tuples(pb): value = _get_value_from_value_pb(value_pb) entity_props[prop_name] = value # Check if the property has an associated meaning. is_list = isinstance(value, list) meaning = _get_meaning(value_pb, is_list=is_list) if meaning is not None: entity_meanings[prop_name] = (meaning, value) # Check if ``value_pb`` was excluded from index. Lists need to be # special-cased and we require all ``exclude_from_indexes`` values # in a list agree. if is_list: exclude_values = set(value_pb.exclude_from_indexes for value_pb in value_pb.array_value.values) if len(exclude_values) != 1: raise ValueError('For an array_value, subvalues must either ' 'all be indexed or all excluded from ' 'indexes.') if exclude_values.pop(): exclude_from_indexes.append(prop_name) else: if value_pb.exclude_from_indexes: exclude_from_indexes.append(prop_name) entity = Entity(key=key, exclude_from_indexes=exclude_from_indexes) entity.update(entity_props) entity._meanings.update(entity_meanings) return entity
def entity_from_protobuf(pb): """Factory method for creating an entity based on a protobuf. The protobuf should be one returned from the Cloud Datastore Protobuf API. :type pb: :class:`gcloud.datastore._datastore_v1_pb2.Entity` :param pb: The Protobuf representing the entity. :rtype: :class:`gcloud.datastore.entity.Entity` :returns: The entity derived from the protobuf. """ key = None if pb.HasField('key'): key = key_from_protobuf(pb.key) entity_props = {} exclude_from_indexes = [] for property_pb in pb.property: value = _get_value_from_property_pb(property_pb) entity_props[property_pb.name] = value # Check if property_pb.value was indexed. Lists need to be # special-cased and we require all `indexed` values in a list agree. if isinstance(value, list): indexed_values = set(value_pb.indexed for value_pb in property_pb.value.list_value) if len(indexed_values) != 1: raise ValueError('For a list_value, subvalues must either all ' 'be indexed or all excluded from indexes.') if not indexed_values.pop(): exclude_from_indexes.append(property_pb.name) else: if not property_pb.value.indexed: exclude_from_indexes.append(property_pb.name) entity = Entity(key=key, exclude_from_indexes=exclude_from_indexes) entity.update(entity_props) return entity