gpt4 book ai didi

java - 在 avro 模式中使用 "default"

转载 作者:可可西里 更新时间:2023-11-01 14:22:43 28 4
gpt4 key购买 nike

根据 Avro docs 中“默认”属性的定义:“此字段的默认值,在读取缺少此字段的实例时使用(可选)。”

这意味着如果缺少相应的字段,则采用默认值。

但似乎并不是这样。考虑以下 student 模式:

{
"type": "record",
"namespace": "com.example",
"name": "Student",
"fields": [{
"name": "age",
"type": "int",
"default": -1
},
{
"name": "name",
"type": "string",
"default": "null"
}
]
}

Schema 表示:如果缺少“age”字段,则将值视为 -1。对于“名称”字段也是如此。

现在,如果我尝试从以下 JSON 构建 Student 模型:

{"age":70}

我得到这个异常:

org.apache.avro.AvroTypeException: Expected string. Got END_OBJECT

at org.apache.avro.io.JsonDecoder.error(JsonDecoder.java:698)
at org.apache.avro.io.JsonDecoder.readString(JsonDecoder.java:227)

默认设置似乎没有按预期工作。那么,default 在这里的作用究竟是什么?

这是用于生成 Student 模型的代码:

Decoder decoder = DecoderFactory.get().jsonDecoder(Student.SCHEMA$, studentJson);
SpecificDatumReader<Student> datumReader = new SpecificDatumReader<>(Student.class);
return datumReader.read(null, decoder);

(Student 类由 Avro 编译器根据学生模式自动生成)

最佳答案

我认为对默认值有一些误解,所以希望我的解释对其他人也有帮助。默认值对于在字段不存在时提供默认值很有用,但这实际上是在实例化 avro 对象时(在您的情况下调用 datumReader.read)但它不允许读取具有不同模式的数据,这就是为什么“模式注册表”的概念对这种情况很有用。

以下代码有效并允许读取您的数据

Decoder decoder = DecoderFactory.get().jsonDecoder(Student.SCHEMA$, "{\"age\":70}");
SpecificDatumReader<Student> datumReader = new SpecificDatumReader<>(Student.class);

Schema expected = new Schema.Parser().parse("{\n" +
" \"type\": \"record\",\n" +
" \"namespace\": \"com.example\",\n" +
" \"name\": \"Student\",\n" +
" \"fields\": [{\n" +
" \"name\": \"age\",\n" +
" \"type\": \"int\",\n" +
" \"default\": -1\n" +
" }\n" +
" ]\n" +
"}");

datumReader.setSchema(expected);
System.out.println(datumReader.read(null, decoder));

如您所见,我正在指定用于“写入”不包含字段“名称”的 json 输入的模式,但是(考虑到您的模式包含默认值)当您打印记录时,您将看到使用您的默认值命名

{"age": 70, "name": "null"}

以防万一,可能知道也可能不知道,“null”并不是真正的空值,而是一个值为“null”的字符串。

关于java - 在 avro 模式中使用 "default",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48985731/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com