Próbuję napisać bardzo prosty schemat avro (łatwy, ponieważ właśnie wskazuję mój bieżący numer), aby zapisać plik danych avro na podstawie danych przechowywanych w formacie json. Sztuczka polega na tym, że jedno pole jest opcjonalne, a jedno z avrotools lub ja nie robi tego dobrze.Generowanie avro schematu z opcjonalnymi wartościami
Celem nie jest napisanie własnego serializera, ostatecznym celem będzie posiadanie tego we flume, jestem we wczesnym stadium.
Dane (prac), w pliku o nazwie so.log:
{
"valid": {"boolean":true}
, "source": {"bytes":"live"}
}
schematu, w pliku o nazwie so.avsc:
{
"type":"record",
"name":"Event",
"fields":[
{"name":"valid", "type": ["null", "boolean"],"default":null}
, {"name":"source","type": ["null", "bytes"],"default":null}
]
}
mogę łatwo wygenerować plik Avro za pomocą następującego polecenia:
java -jar avro-tools-1.7.6.jar fromjson --schema-file so.avsc so.log
Jak dotąd tak dobrze. Chodzi o to, że „źródło” jest opcjonalny, więc spodziewałbym następujące dane zachowują ważność także:
{
"valid": {"boolean":true}
}
Ale działa to samo polecenie daje mi błąd:
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)
Próbowałem wiele odmian schematu, nawet rzeczy, które nie są zgodne ze specyfikacją avro. Schemat, który tutaj pokazuję, jest, o ile mi wiadomo, co mówi specyfikacja.
Czy ktoś wie, co robię źle, i jak mogę rzeczywiście mieć elementy opcjonalne bez pisania własnego serializera?
Dzięki
Widząc ten sam problem tutaj, czy znalazłeś jakiś sposób pracy z AvroTools, aby przekonwertować JSON z opcjonalnymi polami do Avro? Jedynym sposobem obejścia tego problemu jest napisanie opakowania, które wstawiłoby domyślne wartości w JSON przed konwersją, ale to wstyd ... – snooze92
Niestety nie miałem szczęścia. W skrócie JSON jest tylko dla wygody i chociaż schemat może mieć wartość domyślną, dokument JSON, który nie ma tej wartości, jest w rzeczywistości nieprawidłowy. Udokumentowałem niektóre [problemy i rozwiązania, które mieliśmy z avro] (http://thisdwhguy.com/2014/10/27/avro-end-to-end-in-hdfs-part-4-problems-and-solutions/) , mam nadzieję, że to pomoże. – Guillaume
Dzięki za odpowiedź, przeczytam Twój artykuł na blogu! Na razie zrezygnowaliśmy z konwersji JSON> Avro. – snooze92