Генерация схемы 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)


Согласно документации API Java:

использование построителя требует установки всех полей, даже если они пустые

С другой стороны, API Python, по-видимому, допускает нулевые поля. быть действительно необязательным:

Так как поле favourite_color имеет тип ["string", "null"], мы не обязаны указывать это поле

Короче говоря, поскольку большинство инструментов написаны на Java, пустые поля обычно должны указываться явно.

person Guillaume    schedule 03.02.2017