使 Avro 模式中的所有字段都可以为空的最短和最安全的方法是什么?当然,我可以使用模式的 Json 并且只是做 like schema.toString().replaceAll("\"type\": \"long\"", "\"type\": [\"null\", \"long\"]")
,但这是非常丑陋和不安全的解决方案。
问问题
848 次
1 回答
0
下面的代码将为联合类型添加默认值,并首先将类型与空类型交换。您可以为原始类型添加另一个条件,并添加联合类型以及“null”默认值。
import org.apache.avro.JsonProperties;
import org.apache.avro.Schema;
...
String srcSchemaFile = "sample.avsc"; // Source Avro schema file
String targetSchemaFile = "sample_fixed.avsc"; // Target Avro schema file
Schema.Parser avroParser = new Schema.Parser();
Schema schema = avroParser.parse(new File(srcSchemaFile));
makeNullable(schema);
PrintWriter writer = new PrintWriter(targetSchemaFile);
writer.write(schema.toString().replaceAll("defaultXXX", "default"));
writer.close();
...
private static void makeNullable(Schema schema){
if ( schema.getType() != Schema.Type.NULL){
for ( Schema.Field field: schema.getFields()){
if (field.schema().getType() == Schema.Type.UNION){
int nullIndex = IntStream.range(0, field.schema().getTypes().size())
.filter(i -> field.schema().getTypes().get(i).getType() == Schema.Type.NULL )
.findFirst().orElse(-1);
if (nullIndex > 0 && field.defaultVal() == null){
// default property is reserved and cannot be added through addProp method, adding defaultXXX to replace later as a workaround
field.addProp("defaultXXX", JsonProperties.NULL_VALUE);
Collections.swap(field.schema().getTypes(), 0, nullIndex);
}
for (Schema fieldSchema: field.schema().getTypes()){
if (fieldSchema.getType() == Schema.Type.RECORD){
makeNullable(fieldSchema);
} else if (fieldSchema.getType() == Schema.Type.ARRAY){
for (Schema elemSchema: fieldSchema.getElementType().getTypes()){
if (elemSchema.getType() == Schema.Type.RECORD){
makeNullable(elemSchema);
}
}
}
}
}
}
}
}
于 2020-01-16T19:47:19.593 回答