Можно ли разделить схему Apache Avro на несколько файлов?

Я могу сделать,

{
    "type": "record",
    "name": "Foo",
    "fields": [
        {"name": "bar", "type": {
            "type": "record",
            "name": "Bar",
            "fields": [ ]
        }}
    ]
}

и это работает нормально, но предположим, что я хочу разделить схему на два файла, например:

{
    "type": "record",
    "name": "Foo",
    "fields": [
        {"name": "bar", "type": "Bar"}
    ]
}

{
    "type": "record",
    "name": "Bar",
    "fields": [ ]
}

Есть ли у Avro возможность сделать это?

Ответы

Ответ 1

Да, это возможно.

Я сделал это в своем проекте java, указав общие файлы схемы в avro-maven-plugin Пример:

search_result.avro:

{"namespace": "com.myorg.other",
 "type": "record",
 "name": "SearchResult",
 "fields": [
     {"name": "type", "type": "SearchResultType"},
     {"name": "keyWord",  "type": "string"},
     {"name": "searchEngine", "type": "string"},
     {"name": "position", "type": "int"},
     {"name": "userAction", "type": "UserAction"}
 ]
}

search_suggest.avro:

{"namespace": "com.myorg.other",
 "type": "record",
 "name": "SearchSuggest",
 "fields": [
     {"name": "suggest", "type": "string"},
     {"name": "request",  "type": "string"},
     {"name": "searchEngine", "type": "string"},
     {"name": "position", "type": "int"},
     {"name": "userAction", "type": "UserAction"},
     {"name": "timestamp", "type": "long"}
 ]
}

user_action.avro:

{"namespace": "com.myorg.other",
 "type": "enum",
 "name": "UserAction",
 "symbols": ["S", "V", "C"]
}

search_result_type.avro

{"namespace": "com.myorg.other",
 "type": "enum",
 "name": "SearchResultType",
 "symbols": ["O", "S", "A"]
}

Конфигурация avro-maven-plugin:

<plugin>
    <groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.7.4</version>
    <executions>
    <execution>
        <phase>generate-sources</phase>
        <goals>
        <goal>schema</goal>
        </goals>
    <configuration>
     <sourceDirectory>${project.basedir}/src/main/resources/avro</sourceDirectory>
         <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
     <includes>
         <include>**/*.avro</include>
     </includes>
     <imports>
              <import>${project.basedir}/src/main/resources/avro/user_action.avro</import>
              <import>${project.basedir}/src/main/resources/avro/search_result_type.avro</import>
     </imports>
       </configuration>
     </execution>
</executions>
</plugin>

Ответ 2

Вы также можете определить несколько схем внутри одного файла:

schemas.avsc:

[
{
    "type": "record",
    "name": "Bar",
    "fields": [ ]
},
{
    "type": "record",
    "name": "Foo",
    "fields": [
        {"name": "bar", "type": "Bar"}
    ]
}
]

Если вы хотите повторно использовать схемы в нескольких местах, это не очень хорошо, но, на мой взгляд, это значительно улучшает читаемость и техническую поддержку.

Ответ 3

Я предполагаю, что ваша мотивация (как моя собственная) структурирует ваше определение схемы и избегает копирования и вставки-ошибок.

Для этого вы также можете использовать Avro IDL. Это позволяет определять схемы Avro на более высоком уровне. Повторное использование типов возможно внутри одного файла, а также для нескольких файлов.

Чтобы сгенерировать запуск .avsc файлов

$ java -jar avro-tools-1.7.7.jar idl2schemata my-protocol.avdl

Результирующие .avsc файлы будут выглядеть примерно так же, как ваш первоначальный пример, но поскольку они генерируются из .avdl, вы не заблудитесь в подробном json-формате.

Ответ 4

Из того, что мне удалось выяснить до сих пор, нет.

Существует хорошая запись о ком-то, кто закодировал свой метод для этого:

http://www.infoq.com/articles/ApacheAvro

Ответ 5

Порядок импорта в pom.xml имеет значение. Сначала вы должны импортировать подтипы перед обработкой остальных.

<imports>
    <import>${project.basedir}/src/main/resources/avro/Bar.avro</import>
    <import>${project.basedir}/src/main/resources/avro/Foo.avro</import>
</imports>

Это позволит разблокировать код из ошибки undefined name: Bar.avro.