如何为普通JSON添加类型标注以适配Avro Union格式要求
以下是几种常用的简便实现方式:
- 方法1:用Avro官方SDK自动转换(推荐,生产环境适用,无需手动处理类型规则)
各语言的官方Avro库都原生支持直接将原始JSON数据转换为符合Union编码规范的格式,不需要自己手写字段遍历逻辑。
Java示例代码:
// 1. 加载你的Avro Schema Schema schema = new Schema.Parser().parse(yourSchemaStr); // 2. 把原始JSON解析为Avro GenericRecord GenericDatumReader<GenericRecord> reader = new GenericDatumReader<>(schema); GenericRecord record = reader.read(null, DecoderFactory.get().jsonDecoder(schema, originalJsonStr)); // 3. 写出为适配Union要求的JSON ByteArrayOutputStream baos = new ByteArrayOutputStream(); JsonEncoder encoder = EncoderFactory.get().jsonEncoder(schema, baos); new GenericDatumWriter<>(schema).write(record, encoder); encoder.flush(); String targetJson = baos.toString();
运行后输出的就是你要的JSON示例版本2格式,会自动处理所有Union类型的包裹,也会自动匹配Schema中设置的默认值。
Python示例代码:
import avro.schema from avro.io import DatumReader, DatumWriter, JsonDecoder, JsonEncoder import io schema = avro.schema.parse(your_schema_str) # 读取原始JSON reader = DatumReader(schema) decoder = JsonDecoder(schema, io.BytesIO(original_json_str.encode('utf-8'))) record = reader.read(decoder) # 写出目标JSON writer = DatumWriter(schema) output = io.BytesIO() encoder = JsonEncoder(schema, output) writer.write(record, encoder) encoder.flush() target_json = output.getvalue().decode('utf-8')
- 方法2:临时测试用jq脚本快速转换
如果只是少量测试数据要转换,直接写几行jq规则就能实现,针对你给出的Schema,对应jq脚本如下:
{ name: .name, favorite_number: if .favorite_number != null then {"int": .favorite_number} else null end, favorite_color: .favorite_color }
直接把原始JSON传入这个脚本就能输出目标格式,字段多的话可以批量扩展规则即可。
注意:如果你的Avro Union类型顺序调整,比如把非null类型放在null前面,转换逻辑不需要改,官方SDK会自动处理类型匹配,不需要手动调整。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

