0

使 Avro 模式中的所有字段都可以为空的最短和最安全的方法是什么?当然,我可以使用模式的 Json 并且只是做 like schema.toString().replaceAll("\"type\": \"long\"", "\"type\": [\"null\", \"long\"]"),但这是非常丑陋和不安全的解决方案。

4

1 回答 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 回答