Avro Generic Record 不考虑别名
Avro Generic Record not taking aliases into account
我有一些 JsonData(fastxml.jackson 对象),我想将其转换为 GenericAvro 记录。因为我不知道我将获得什么数据,所以只有模式存储库中有可用的 Avro 模式。我无法预定义 类。因此,通用记录。
当我漂亮地打印我的模式时,我可以看到我的 keys/values 和它们的别名。然而,通用记录 "put" 方法似乎不知道这些别名。
我得到以下异常 Exception in thread "main" org.apache.avro.AvroRuntimeException: Not a valid schema field: device/id
这是设计使然吗?我怎样才能让这个模式也看到别名?
架构摘录:
"fields" : [ {
"name" : "device_id",
"type" : "long",
"doc" : " The id of the device.",
"aliases" : [ "deviceid", "device/id" ]
}, {
............
}]
代码:
def jsonToAvro(jSONObject: JsonNode, schema: Schema): GenericRecord = {
val converter = new JsonAvroConverter
println(jSONObject.toString) // correct
println(schema.toString(true)) // correct
println(schema.getField("device_id")) //correct
println(schema.getField("device_id").aliases()toString) //correct
val avroRecord = new GenericData.Record(schema)
val iter = jSONObject.fields()
while (iter.hasNext) {
import java.util
val e = jSONObject.fields()
val entry = iter.next.asInstanceOf[util.Map.Entry[String, Nothing]]
println(s"adding ${entry.getKey.toString} and ${entry.getValue} with ${entry.getValue.getClass.getName}") // adding device/id and 8711 with com.fasterxml.jackson.databind.node.IntNode
avroRecord.put(entry.getKey.toString, entry.getValue) // throws
}
avroRecord
}
看来架构在阅读时只有这么灵活。
编写 AVRO 只查看当前字段名称。
不仅如此,我还在我的字段名称中使用 "/" (json),这是 不支持的 作为字段名称。
模式验证在别名中时不会报错,所以这可能有效(尚未测试)
我试过 Avro 1.8.2,当我将 json 字符串读入 GenericRecord 时它仍然抛出这个异常:
org.apache.avro.AvroTypeException: Expected field name not found:
但是两年前我看到一些样本正确使用了别名:
所以我猜 Avro 最近改变了这种行为
我有一些 JsonData(fastxml.jackson 对象),我想将其转换为 GenericAvro 记录。因为我不知道我将获得什么数据,所以只有模式存储库中有可用的 Avro 模式。我无法预定义 类。因此,通用记录。
当我漂亮地打印我的模式时,我可以看到我的 keys/values 和它们的别名。然而,通用记录 "put" 方法似乎不知道这些别名。
我得到以下异常 Exception in thread "main" org.apache.avro.AvroRuntimeException: Not a valid schema field: device/id
这是设计使然吗?我怎样才能让这个模式也看到别名?
架构摘录:
"fields" : [ {
"name" : "device_id",
"type" : "long",
"doc" : " The id of the device.",
"aliases" : [ "deviceid", "device/id" ]
}, {
............
}]
代码:
def jsonToAvro(jSONObject: JsonNode, schema: Schema): GenericRecord = {
val converter = new JsonAvroConverter
println(jSONObject.toString) // correct
println(schema.toString(true)) // correct
println(schema.getField("device_id")) //correct
println(schema.getField("device_id").aliases()toString) //correct
val avroRecord = new GenericData.Record(schema)
val iter = jSONObject.fields()
while (iter.hasNext) {
import java.util
val e = jSONObject.fields()
val entry = iter.next.asInstanceOf[util.Map.Entry[String, Nothing]]
println(s"adding ${entry.getKey.toString} and ${entry.getValue} with ${entry.getValue.getClass.getName}") // adding device/id and 8711 with com.fasterxml.jackson.databind.node.IntNode
avroRecord.put(entry.getKey.toString, entry.getValue) // throws
}
avroRecord
}
看来架构在阅读时只有这么灵活。 编写 AVRO 只查看当前字段名称。
不仅如此,我还在我的字段名称中使用 "/" (json),这是 不支持的 作为字段名称。
模式验证在别名中时不会报错,所以这可能有效(尚未测试)
我试过 Avro 1.8.2,当我将 json 字符串读入 GenericRecord 时它仍然抛出这个异常:
org.apache.avro.AvroTypeException: Expected field name not found:
但是两年前我看到一些样本正确使用了别名:
所以我猜 Avro 最近改变了这种行为