如何在 Avro Schema 中定义复杂类型
How do I define a complex type in an Avro Schema
我查看了 avro 文档以及几个在线示例(以及类似的 Whosebug 问题)。然后我尝试定义一个 avro 模式,并且不得不逐步退出字段以确定我的问题是什么(来自 python 中的 avro 库的错误消息并不像人们希望的那样有用)。我有一个 JSON 文档,我想将其转换为 Avro,我需要为此目的指定一个模式(使用 avro-tools 从 json 生成模式没有按预期工作并且尝试将 json 转换为 avro 时产生 AvroTypeException)。我正在使用 Avro 版本 1.7.7。这是我要为其定义 avro 架构的 JSON 文档:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
我能够为非复杂类型定义架构,但不能为复杂的 "siteId" 字段定义架构:
{
"namespace" : "com.example",
"name" : "methodEvent",
"type" : "record",
"fields" : [
{"name": "method", "type": "string"},
{"name": "code", "type": "int"},
{"name": "reason", "type": "string"}
{"name": "siteId", "type": [ "null", "string" ]}
]
}
尝试使用之前的架构将 Json 对象转换为 avro 会产生一个 avro.io.AvroTypeException:数据 [参见上面的 JSON 对象] 不是架构 [请参阅上面的 Avro 模式对象]。我只在尝试在模式中定义一个字段来表示上面 json.
中的 "siteId" 字段时才看到此错误
我能够使用以下架构解决问题:
{
"namespace" : "com.example",
"name" : "methodEvent",
"type" : "record",
"fields" : [
{"name": "method", "type": "string"},
{"name": "code", "type": "int"},
{"name": "reason", "type": "string"}
{
"name": "siteId",
"type": {
"name" : "siteId",
"type" : "record",
"fields" : [
"name" : "string",
"type" : [ "null", "string" ]
]
}
},
"default" : null
]
}
Avro 的 python 实现表示联合不同于它们的 JSON 编码:它 "unwraps" 它们,所以 siteId
字段应该只是字符串,没有包装对象。请参阅下面的几个示例。
有效 JSON 编码
非空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
有效 python 个对象(内存中表示)
非空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
请注意,null
unwrapped in both cases which is why 不工作。
不幸的是,python 实现目前没有 JSON decoder/encoder (AFAIK),因此没有简单的方法在两种表示之间进行转换。根据您的 JSON 编码数据的来源,最简单的方法可能是将其编辑为不再包装联合实例。
我查看了 avro 文档以及几个在线示例(以及类似的 Whosebug 问题)。然后我尝试定义一个 avro 模式,并且不得不逐步退出字段以确定我的问题是什么(来自 python 中的 avro 库的错误消息并不像人们希望的那样有用)。我有一个 JSON 文档,我想将其转换为 Avro,我需要为此目的指定一个模式(使用 avro-tools 从 json 生成模式没有按预期工作并且尝试将 json 转换为 avro 时产生 AvroTypeException)。我正在使用 Avro 版本 1.7.7。这是我要为其定义 avro 架构的 JSON 文档:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
我能够为非复杂类型定义架构,但不能为复杂的 "siteId" 字段定义架构:
{
"namespace" : "com.example",
"name" : "methodEvent",
"type" : "record",
"fields" : [
{"name": "method", "type": "string"},
{"name": "code", "type": "int"},
{"name": "reason", "type": "string"}
{"name": "siteId", "type": [ "null", "string" ]}
]
}
尝试使用之前的架构将 Json 对象转换为 avro 会产生一个 avro.io.AvroTypeException:数据 [参见上面的 JSON 对象] 不是架构 [请参阅上面的 Avro 模式对象]。我只在尝试在模式中定义一个字段来表示上面 json.
中的 "siteId" 字段时才看到此错误我能够使用以下架构解决问题:
{
"namespace" : "com.example",
"name" : "methodEvent",
"type" : "record",
"fields" : [
{"name": "method", "type": "string"},
{"name": "code", "type": "int"},
{"name": "reason", "type": "string"}
{
"name": "siteId",
"type": {
"name" : "siteId",
"type" : "record",
"fields" : [
"name" : "string",
"type" : [ "null", "string" ]
]
}
},
"default" : null
]
}
Avro 的 python 实现表示联合不同于它们的 JSON 编码:它 "unwraps" 它们,所以 siteId
字段应该只是字符串,没有包装对象。请参阅下面的几个示例。
有效 JSON 编码
非空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
有效 python 个对象(内存中表示)
非空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
空 siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
请注意,null
unwrapped in both cases which is why
不幸的是,python 实现目前没有 JSON decoder/encoder (AFAIK),因此没有简单的方法在两种表示之间进行转换。根据您的 JSON 编码数据的来源,最简单的方法可能是将其编辑为不再包装联合实例。