org.apache.avro.AvroTypeException:未知的联合分支 [英] org.apache.avro.AvroTypeException: Unknown union branch
问题描述
我正在使用以下Avro模式:
I'm using this Avro schema:
prices-state.avsc
{
"namespace": "com.company.model",
"name": "Product",
"type": "record",
"fields": [
{
"name": "product_id",
"type": "string"
},
{
"name": "sale_prices",
"type": {
"name": "sale_prices",
"type": "record",
"fields": [
{
"name": "default",
"type": {
"name": "default",
"type": "record",
"fields": [
{
"name": "order_by_item_price_by_item",
"type": [
"null",
{
"name": "markup_strategy",
"type": "record",
"fields": [
{
"name": "type",
"type": {
"name": "type",
"type": "enum",
"symbols": ["margin", "sale_price"]
}
}
]
}
]
},
{"name": "order_by_item_price_by_weight", "type": ["null", "string"]},
{"name": "order_by_weight_price_by_weight", "type": ["null", "string"]}
]
}
}
]
}
}
]
}
它可以在此网站上正确验证,所以我假设使用该模式有效.
It validates properly on this website so I'm assuming the schema is valid.
我在构建JSON文件时遇到问题,然后应使用上述架构对其进行编码.
I'm having issues building a JSON file that should then be encoded using the above schema.
我正在使用此JSON进行一些测试:
I'm using this JSON for some testing:
test.json
{
"product_id": "123",
"sale_prices": {
"default": {
"order_by_item_price_by_item": {
"markup_strategy": {
"type": {"enum": "margin"}
}
},
"order_by_item_price_by_weight": null,
"order_by_weight_price_by_weight": null
}
}
}
运行java -jar avro-tools-1.8.2.jar fromjson --schema-file prices-state.avsc test.json
时,我得到:
线程"main"中的异常org.apache.avro.AvroTypeException:未知的联合分支markup_strategy
Exception in thread "main" org.apache.avro.AvroTypeException: Unknown union branch markup_strategy
我在此处读到,我必须将东西包装在联合体内因为使用JSON编码,所以我尝试了不同的组合,但似乎没人能用.
I read here that I have to wrap things inside unions because of JSON Encoding so I tried different combinations but no one seemed to work.
推荐答案
这是一个命名空间解析问题.以这个简化的模式为例:
It was a namespace resolution issue. Take this simplified schema as an example:
test.avsc
{
"name": "Product",
"type": "record",
"fields": [
{
"name": "order_by_item_price_by_item",
"type": [
"null",
{
"type": "record",
"name": "markup_strategy",
"fields": [{
"name": "type",
"type": {
"name": "type",
"type": "enum",
"symbols": ["margin", "sale_price"]
}
}]
}
]
}
]
}
使用以下JSON可以很好地验证
With the following JSON it validates just fine
test.json
{
"order_by_item_price_by_item": {
"markup_strategy": {
"type": "margin"
}
}
}
现在,如果要在架构顶部添加名称空间,例如
Now if you were to add a namespace on top of your schema like
test.avsc
{
"namespace": "test",
"name": "Product",
"type": "record",
"fields": [
...
然后,您还需要更改您的 test.json ,否则您将得到
Then you would need to change your test.json as well or you'll get
线程"main"中的异常org.apache.avro.AvroTypeException:未知的联合分支markup_strategy
Exception in thread "main" org.apache.avro.AvroTypeException: Unknown union branch markup_strategy
final_test.json
{
"order_by_item_price_by_item": {
"test.markup_strategy": {
"type": "margin"
}
}
}
因此,当在联合类型中并且您使用用户指定的名称对JSON编码的Avro命名类型(记录,固定或枚举)时,该类型的名称也必须在名称空间名称之前添加分辨率.
So when inside a union type and you're JSON encoding an Avro's named type (record, fixed or enum) where the user-specified name is used then the name of that type needs to be prepended with the namespace name too for resolution.