def __init__(self, document_data): super(DocumentExtractorForUpdate, self).__init__(document_data) self.top_level_paths = sorted( [FieldPath.from_string(key) for key in document_data]) tops = set(self.top_level_paths) for top_level_path in self.top_level_paths: for ancestor in top_level_path.lineage(): if ancestor in tops: raise ValueError("Conflicting field path: {}, {}".format( top_level_path, ancestor)) for field_path in self.deleted_fields: if field_path not in tops: raise ValueError( "Cannot update with nest delete: {}".format(field_path))
def extract_fields(document_data, prefix_path, expand_dots=False): """Do depth-first walk of tree, yielding field_path, value""" if not document_data: yield prefix_path, _EmptyDict else: for key, value in sorted(six.iteritems(document_data)): if expand_dots: sub_key = FieldPath.from_string(key) else: sub_key = FieldPath(key) field_path = FieldPath(*(prefix_path.parts + sub_key.parts)) if isinstance(value, dict): for s_path, s_value in extract_fields(value, field_path): yield s_path, s_value else: yield field_path, value
def __init__(self, document_data): super(DocumentExtractorForUpdate, self).__init__(document_data) self.top_level_paths = sorted( [FieldPath.from_string(key) for key in document_data] ) tops = set(self.top_level_paths) for top_level_path in self.top_level_paths: for ancestor in top_level_path.lineage(): if ancestor in tops: raise ValueError( "Conflicting field path: {}, {}".format( top_level_path, ancestor ) ) for field_path in self.deleted_fields: if field_path not in tops: raise ValueError( "Cannot update with nest delete: {}".format(field_path) )