【问题标题】:How to make all fields in Avro schema nullable?如何使 Avro 模式中的所有字段都可以为空?
【发布时间】:2019-05-12 07:16:07
【问题描述】:

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

【问题讨论】:

    标签: java avro avro-tools


    【解决方案1】:

    下面的代码将为联合类型添加默认值,并首先将类型与空类型交换。您可以为原始类型添​​加另一个条件,并添加联合类型以及“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-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 2022-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多