Генериране на avro схема с незадължителни стойности

Опитвам се да напиша много лесна схема на avro (лесна, защото просто посочвам текущия си проблем), за да напиша файл с данни на avro въз основа на данни, съхранени във формат json. Номерът е, че едно поле не е задължително и едно от avrotools или аз не го прави правилно.

Целта не е да напиша собствен сериализатор, крайната цел ще бъде това да е в потока, аз съм в ранните етапи.

Данните (работи), във файл с име 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. Схемата, която показвам тук, е, доколкото знам, това, което спецификацията казва, че трябва да бъде.

Някой знае ли какво правя погрешно и как всъщност мога да имам незадължителни елементи, без да напиша собствен сериализатор?

Благодаря,


person Guillaume    schedule 08.04.2014    source източник
comment
Виждайки същия проблем тук, намерихте ли някакъв начин да работите с AvroTools за конвертиране на JSON с незадължителни полета в Avro? Единственото решение, за което мога да се сетя в момента, е да напиша обвивка, която да вмъква стойности по подразбиране в JSON преди преобразуването, но това е жалко...   -  person snooze92    schedule 08.09.2014
comment
За съжаление нямах много късмет. Накратко, JSON е само за удобство и въпреки че дадена схема може да има стойност по подразбиране, JSON документ, в който липсва тази стойност, всъщност не е валиден. Документирах някои проблеми и решения, които имахме с avro, надявам се, че може да помогне.   -  person Guillaume    schedule 03.11.2014
comment
Благодаря за отговора, ще прочета статията в блога ти! Засега се отказахме от JSON › Avro конвертирането.   -  person snooze92    schedule 04.11.2014
comment
В документацията на Avro се казва, че използването на конструктор изисква настройка на всички полета, дори ако са нулеви. Може да е свързано с вашия случай. Проверете avro.apache.org/docs/1.7.7/gettingstartedjava.html   -  person haltunbay    schedule 20.08.2015
comment
Вижте stackoverflow.com/questions/27485580/   -  person Pavel Bernshtam    schedule 08.08.2016


Отговори (1)


Според документация на Java API:

използването на конструктор изисква настройка на всички полета, дори ако те са нулеви

API на python, от друга страна, изглежда позволява нулеви полета да бъде наистина незадължително:

Тъй като полето favorite_color има тип ["string", "null"], от нас не се изисква да посочваме това поле

Накратко, тъй като повечето инструменти са написани на Java, нулевите полета обикновено трябва да бъдат изрично дадени.

person Guillaume    schedule 03.02.2017