Python 如何在Avro模式中定义复杂类型
我已经阅读了avro文档以及一些在线示例(以及类似的StackOverflow问题)。然后,我尝试定义一个avro模式,并且必须逐步退出字段以确定我的问题是什么(来自python中avro库的错误消息没有人们希望的那么有用)。我有一个JSON文档,我想将其转换为Avro,我需要为此指定一个模式(使用Avro工具从JSON生成模式没有按预期工作,并且在尝试将JSON转换为Avro时产生了AvroTypeException)。我使用的是Avro版本1.7.7。下面是我想为其定义avro模式的JSON文档:Python 如何在Avro模式中定义复杂类型,python,json,avro,Python,Json,Avro,我已经阅读了avro文档以及一些在线示例(以及类似的StackOverflow问题)。然后,我尝试定义一个avro模式,并且必须逐步退出字段以确定我的问题是什么(来自python中avro库的错误消息没有人们希望的那么有用)。我有一个JSON文档,我想将其转换为Avro,我需要为此指定一个模式(使用Avro工具从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”字段定义模式:
尝试使用前面的模式将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编码:它“解包”它们,因此
siteId
字段应该只是字符串,没有包装对象。下面是一些例子
有效的JSON编码
非空站点ID
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
空siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
有效的python对象(内存中表示)
非空站点ID
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
空siteid
:
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": {
"string": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": "a1283632-121a-4a3f-9560-7b73830f94j8"
}
{
"method": "Do_Thing",
"code": 200,
"reason": "OK",
"siteId": null
}
请注意,null
s在这两种情况下都是无效的,这就是它不工作的原因
不幸的是,python实现目前没有JSON解码器/编码器(AFAIK),因此没有简单的方法在这两种表示之间进行转换。根据JSON编码数据的来源,最简单的方法可能是将其编辑为不再包装联合实例。这部分有效(仅当siteId有值时)。如果json对象中的“siteId”为null,则会发生与前面所述相同的错误。