def _serialize_union(self, schema, datum): """ With union schema has multiple possible schemas. We iterate over possible schemas and see which one fits `datum` passed. Union serialization: if null: "null" else: {"<type>": value} Then used one that matches to serialize `datum` :param schema: Avro schema for this union :param datum: Data to serialize :return: dict {"type": value} or "null" """ for candiate_schema in schema.schemas: if validate(candiate_schema, datum): if candiate_schema.type == "null": return self._serialize_null() else: field_type_name = candiate_schema.type if isinstance(candiate_schema, avro.schema.NamedSchema): field_type_name = candiate_schema.name return { field_type_name: self._serialize_data(candiate_schema, datum) } raise schema.AvroTypeException(schema, datum)
def _deserialize_union(self, schema, annotated_datum): """ With union schema has multiple possible schemas. We iterate over possible schemas and see which one matches the key that was in the json. Union serialization: if null: None else: value Then used one that matches to deserialize `annotated_datum` :param schema: Avro schema for this union :param annotated_datum: Data with Avro json annotation to deserialize :return: dict {"type": value} or "null" """ if not annotated_datum: return self._deserialize_null() if not isinstance(annotated_datum, dict): raise AvroTypeException(schema, annotated_datum) key = list(annotated_datum.keys())[0] for candidate_schema in schema.schemas: if isinstance(candidate_schema, avro.schema.NamedSchema): if candidate_schema.name == key: return self._deserialize_data(candidate_schema, annotated_datum[key]) else: if candidate_schema.type == key: return self._deserialize_data(candidate_schema, annotated_datum[key]) raise schema.AvroTypeException(schema, datum)