2014-04-08 42 views
6

我想写一个非常简单的avro模式(因为我只是指出了我当前的问题),以基于以json格式存储的数据编写avro数据文件。诀窍是一个字段是可选的,而一个avrotools或者我没有做正确的。使用可选值生成avro模式

目标不是写我自己的连载者,而是要在水槽里有这个,我处于早期阶段。

的数据(作品),文件名为so.log:

{ 
    "valid": {"boolean":true} 
, "source": {"bytes":"live"} 
} 

架构,在一个文件名为so.avsc:

{ 
    "type":"record", 
    "name":"Event", 
    "fields":[ 
     {"name":"valid", "type": ["null", "boolean"],"default":null} 
    , {"name":"source","type": ["null", "bytes"],"default":null} 
    ] 
} 

我可以很容易地产生的Avro文件用下面的命令:

java -jar avro-tools-1.7.6.jar fromjson --schema-file so.avsc so.log 

到目前为止好。问题是,“源”是可选的,所以我希望下面的数据是有效的,以及:

{ 
    "valid": {"boolean":true} 
} 

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

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) 

我曾尝试架构中的很多变体,甚至不遵循avro规范的东西。就我所知,我在这里展示的模式是,规范说明它应该是什么。

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

感谢,

+0

在这里看到同样的问题,你有没有找到任何方式与AvroTools合作,将可选字段的JSON转换为Avro?我现在唯一能想到的解决方法是编写一个包装器,它可以在转换之前在JSON中插入默认值,但这真是太遗憾了...... – snooze92

+1

可悲的是我没有太多的运气。简而言之,JSON仅仅是为了方便起见,尽管模式可以具有默认值,但缺少该值的JSON文档实际上是无效的。我记录了一些[问题和解决方案,我们与avro](http://thisdwhguy.com/2014/10/27/avro-end-to-end-in-hdfs-part-4-problems-and-solutions/)希望它能提供帮助。 – Guillaume

+0

感谢您的回答,我会阅读您的博客文章!我们现在放弃了JSON> Avro转换。 – snooze92

回答

1

根据Java API的documentation

using a builder requires setting all fields, even if they are null

python API,在另一方面,似乎让空字段,真正做到otional:

Since the field favorite_color has type ["string", "null"], we are not required to specify this field

简而言之,由于大多数工具都是用java编写的,所以通常必须明确给出空字段。