web-dev-qa-db-fra.com

Puis-je fractionner un schéma Apache Avro sur plusieurs fichiers?

Je peux faire,

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

et cela fonctionne bien, mais en supposant que je veuille diviser le schéma en deux fichiers tels que:

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

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

Avro a-t-il la capacité de le faire?

19
Owen

Oui c'est possible.

C'est ce que j'ai fait dans mon projet Java en définissant les fichiers de schéma courants dans avro-maven-plugin Exemple:

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"]
}

configuration du plugin avro-maven:

<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>
28
AlexTiunov

Vous pouvez également définir plusieurs schémas à l'intérieur d'un fichier:

schemas.avsc:

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

Si vous voulez réutiliser les schémas à plusieurs endroits, ce n'est pas super Nice mais cela améliore beaucoup la lisibilité et la maintenabilité à mon avis.

20
Michael

Je suppose que votre motivation est (comme la mienne) de structurer votre définition de schéma et d’éviter les erreurs de copier-coller.

Pour cela, vous pouvez également utiliser Avro IDL . Cela permet de définir des schémas avro à un niveau supérieur. La réutilisation de types est possible dans le même fichier et aussi dans plusieurs fichiers .

Pour générer les fichiers .avsc, exécutez

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

Les fichiers .avsc obtenus ressembleront beaucoup à votre exemple initial, mais comme ils sont générés à partir du fichier .avdl, vous ne vous perdrez pas au format json.

5
fab

L'ordre des importations dans pom.xml est important. Vous devez d'abord importer les sous-types avant de traiter les autres. 

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

Cela débloquerait le codegen d'émettre l'erreur undefined name: Bar.avro.

0
Jack Yeh

Vous devez importer le fichier avsc dans le plugin avro-maven où vous avez écrit le schéma d'objet que vous souhaitez réutiliser

<plugin>
<groupId>org.Apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>${avro.maven.plugin.version}</version>
<configuration>
    <stringType>String</stringType>
</configuration>
<executions>
    <execution>
        <phase>generate-sources</phase>
        <goals>
            <goal>schema</goal>
        </goals>
        <configuration>
            <sourceDirectory>src/main/Java/com/xyz/avro</sourceDirectory> // Avro directory
            <imports>
                <import>src/main/Java/com/xyz/avro/file.avsc</import> // Import here
            </imports>
        </configuration>
    </execution>
</executions>

0
blueberry

D'après ce que j'ai pu comprendre jusqu'à présent, non.

Il existe un bon article sur quelqu'un qui a codé sa propre méthode pour le faire ici:

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

0
E Smith