给定的示例模式包含一个字段,该字段是null和string的联合,
{
"type":"record",
"name":"DataFlowEntity",
"namespace":"org.sdf.manage.commons.server",
"fields":
[
{"name":"dataTypeGroupName","type":["null","string"]},
{"name":"dataTypeName","type":"string"},
{"name":"dataSchemaVersion","type":"string"}
]
}
我想转换以下 json 对象,
{
"dataTypeGroupName": "dg_1",
"dataTypeName": "dt_1",
"dataSchemaVersion": "1"
}
转换成对应于上述模式的avro对象。我用Avro的JsonDecoder用下面描述的代码snppet试了一下,
String dataFlowEntity = "{\"dataTypeGroupName\": \"dg_1\", \"dataTypeName\": \"dt_1\", \"dataSchemaVersion\": \"1\"}";
Schema schema = DataFlowEntity.SCHEMA$;
InputStream inputStream = new ByteArrayInputStream(dataFlowEntity.getBytes());
DataInputStream dInputStream = new DataInputStream(inputStream);
Decoder decoder = DecoderFactory.get().jsonDecoder(schema, dInputStream);
DatumReader<DataFlowEntity> datumReader = new GenericDatumReader<DataFlowEntity>(schema);
DataFlowEntity dataFlowEntityObject = DataFlowEntity.newBuilder().build();
dataFlowEntityObject = datumReader.read(null, decoder);
它会异常失败,
threw exception [org.apache.avro.AvroRuntimeException: org.apache.avro.AvroRuntimeException: Field dataTypeGroupName type:UNION pos:0 not set and has no default value] with root cause
org.apache.avro.AvroRuntimeException: Field dataTypeGroupName type:UNION pos:0 not set and has no default value
at org.apache.avro.generic.GenericData.getDefaultValue(GenericData.java:874)
at org.apache.avro.data.RecordBuilderBase.defaultValue(RecordBuilderBase.java:135)
有一个新的JSON编码器正在开发中,应该可以解决这个常见问题:
https://issues.apache.org/jira/browse/AVRO-1582
https://github.com/zolyfarkas/avro
这似乎是很多人在处理Avro时遇到的一个常见问题。
如果您将JSON切换到此,它应该可以工作:
{
"dataTypeGroupName": {"string" : "dg_1"},
"dataTypeName": "dt_1",
"dataSchemaVersion": "1"
}
这是因为Avro使用对象类型包装对联合进行编码,不幸的是,即使是简单的联合也表示可选类型,不需要JSON对象包装来消除歧义。Avro的意图似乎从来不是生成友好的JSON,更重要的是使用JSON作为序列化格式。
更多详情:https://avro.apache.org/docs/1.7.7/spec.html#json_encoding
查看此项目:https://github.com/allegro/hermes/pull/749/files
您对JsonAvroConverter感兴趣。它从json(没有联合类型)反序列化为Avro生成的对象(有联合类型)。实际上,它从union上的类型模式中获取并逐个尝试它们。它在我们的情况下非常有效。
这就是工作:https://github.com/allegro/json-avro-converter/blob/master/converter/src/main/java/tech/allegro/schema/json2avro/converter/JsonGenericRecordReader.java
问候!
如果可以选择使用node.js,则可以使用avsc
为您进行转换。使用wrapUnions
设置调用clone
将自动将值包装到它们匹配的第一个联合分支中。
使用您的示例:
var avsc = require('avsc');
var type = avsc.parse({
"type":"record",
"name":"DataFlowEntity",
"namespace":"org.sdf.manage.commons.server",
"fields": [
{"name":"dataTypeGroupName","type":["null","string"]},
{"name":"dataTypeName","type":"string"},
{"name":"dataSchemaVersion","type":"string"}
]
}, {wrapUnions: true});
var invalidRecord = {
"dataTypeGroupName": "dg_1",
"dataTypeName": "dt_1",
"dataSchemaVersion": "1"
};
var validRecord = type.clone(invalidRecord, {wrapUnions: true});
// == {
// "dataTypeGroupName":{"string":"dg_1"},
// "dataTypeName":"dt_1",
// "dataSchemaVersion":"1"
// }
有一个网站这样做,但我想要一个图书馆或CLI。 谢了!
如何使用用户指定的架构将dataframe转换为Avro格式?
使用字符串数组为对象创建avro模式的正确方法是什么? 我试图创建avro模式的对象,有字符串数组根据官方文档?但我得到错误。 https://avro.apache.org/docs/1.8.1/spec.html [错误]无法执行目标组织。阿帕奇。avro:avro maven插件:1.8.2:项目电子邮件上的模式(默认值):目标组织的执行默认值。阿帕奇。avro:avro maven插件:1
问题内容: 我正在使用org.json库将Object转换为Json格式。请检查以下代码片段。 它显示了这样的输出: 它显示为空白并添加了卷曲基数。这是什么意思?有人遇到过这个问题吗? 问题答案: 首先,我强烈建议您不要使用此库(org.json),这是一个非常古老且不受支持的库(据我所知)。我建议杰克逊或格森。 但是,如果您确实需要JSONObject,则可以将getter添加到枚举中: 序列化
我有一个字符串(jsonData)通过Jackson对象映射器映射到json,如下所示,映射到JaxB。 我能够很好地映射到上面的字符串。然而,我在映射到jooq JSON对象时遇到了问题。我想我现在必须将jsonData转换为jooq JSON。 我该怎么做? 或者我必须创建某种包装? 由jooq配置的DTO
问题内容: 有没有一种方法可以在不使用Python定义架构的情况下将JSON字符串转换为Avro?还是只有Java才能处理的事情? 问题答案: Apache Avro™1.7.6入门(Python) :