使用可选值生成avro架构

Gui*_*ume 7 flume avro

我正在尝试编写一个非常简单的avro架构(很简单因为我只是指出我当前的问题)来编写基于json格式存储的数据的avro数据文件.诀窍是一个字段是可选的,其中一个avrotools或我做得不对.

我的目标不是编写自己的序列化器,最终将会有这个,我处于早期阶段.

数据(工作),在名为so.log的文件中:

{
  "valid":  {"boolean":true}
, "source": {"bytes":"live"}
}
Run Code Online (Sandbox Code Playgroud)

该架构位于名为so.avsc的文件中:

{
  "type":"record",
  "name":"Event",
  "fields":[
      {"name":"valid", "type": ["null", "boolean"],"default":null}
    , {"name":"source","type": ["null", "bytes"],"default":null}
  ]
}
Run Code Online (Sandbox Code Playgroud)

我可以使用以下命令轻松生成avro文件:

java -jar avro-tools-1.7.6.jar fromjson --schema-file so.avsc so.log
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.问题是"源"是可选的,所以我希望以下数据也是有效的:

{
  "valid": {"boolean":true}
}
Run Code Online (Sandbox Code Playgroud)

但是运行相同的命令会给我错误:

Exception in thread "main" org.apache.avro.AvroTypeException: Expected start-union. Got END_OBJECT
at org.apache.avro.io.JsonDecoder.error(JsonDecoder.java:697)
at org.apache.avro.io.JsonDecoder.readIndex(JsonDecoder.java:441)
at org.apache.avro.io.ResolvingDecoder.doAction(ResolvingDecoder.java:229)
at org.apache.avro.io.parsing.Parser.advance(Parser.java:88)
at org.apache.avro.io.ResolvingDecoder.readIndex(ResolvingDecoder.java:206)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:155)
at org.apache.avro.generic.GenericDatumReader.readField(GenericDatumReader.java:193)
at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:183)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:151)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:142)
at org.apache.avro.tool.DataFileWriteTool.run(DataFileWriteTool.java:99)
at org.apache.avro.tool.Main.run(Main.java:84)
at org.apache.avro.tool.Main.main(Main.java:73)
Run Code Online (Sandbox Code Playgroud)

我确实在架构中尝试了很多变化,甚至是那些不符合avro规范的东西.据我所知,我在这里展示的架构是规范应该是什么.

有人会知道我做错了什么,以及如何在不编写自己的序列化器的情况下实际拥有可选元素?

谢谢,

Gui*_*ume 5

根据Java API的文档:

使用构建器需要设置所有字段,即使它们为空

另一方面,python API 似乎允许 null 字段确实是可选的

由于字段 favorite_color 的类型为 ["string", "null"],因此我们不需要指定该字段

简而言之,由于大多数工具都是用 Java 编写的,因此通常必须显式给出 null 字段。