java - 如何使 Avro 模式中的所有字段都可以为空?

标签 java avro avro-tools

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

最佳答案

下面的代码将为联合类型添加默认值,并首先将类型与空类型交换。您可以为基元类型添加另一个条件,并添加联合类型和“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);
                            }
                        }
                    }
                }
             }
        }
    }
}

关于java - 如何使 Avro 模式中的所有字段都可以为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56096996/

相关文章:

java - 将一个 vector 保存到另一个 vector 中并清除第一个 vector

java - 自动登录网站

java - 无需重复字符序列的Passay密码

avro 时间戳字段上的配置单元外部表返回时间长

python - 当属性匹配时,如何使用 Python 序列化 Avro 中的联合字段

java - 使用 JRE 7u45 运行小程序时出现权限属性警告

scala - 在 Scala 中导入 avro 模式

java - IdentityMapCapacity 在架构注册表中意味着什么

scala - Spark Dataframe 以 avro 格式写入 kafka 主题?

json - 如何将 json 模式转换为 avro 模式