2017-11-07 3 views
0

私はScalaのAvro用Java APIを使用し、Avro GenericRecord/SchemaBuilder APIを使用して既存のレコードスキーマにフィールドを追加する簡単なプログラマチックな方法があるのだろうか?1つのフィールドを追加してJava API経由でAvroスキーマを拡張する

+0

これまでに試したことを共有できますか?私はその質問が完全にはっきりしていないと思う。すでにインスタンス化されているGenericRecordオブジェクトに新しいフィールドを追加しますか? – hlagos

+0

私がしたいのは、プログラム的なスキーマの進化です:私はGenericRecordを持っており、getSchema()でスキーマを取得できます。そのスキーマに基づいて新しいスキーマを作成し、もう1つのフィールドを追加したいと思います。私が今までに見つけたのは、既存のスキーマからすべてのフィールドを取得し、それらを非常に扱いにくいものにすることです(デフォルトのものなど)。新しいSchemaBuilderに追加し、新しいフィールドを追加します。ちょうど私がこのコードをすべて自分で書く必要があるのか​​と思っています。 SchemaBuilder API – longliveenduro

+0

では、あなたが今までに持っていたコードとあなたの期待とであなたの質問を更新すると便利です。 – hlagos

答えて

2

簡単な方法はありませんが、私はあなたが何をしようとしているのか正確に知っています。

既存のスキーマ(SchemaBuilderなど)を動的に拡張する例です。

Schema schema = SchemaBuilder 
      .record("schema_base").namespace("com.namespace.test") 
      .fields() 
      .name("longField").type().longType().noDefault() 
      .name("stringField").type().stringType().noDefault() 
      .name("booleanField").type().booleanType().noDefault() 
      .name("optionalStringColumn").type().optional().stringType() 
      .endRecord(); 



    List<Schema.Field> field_list = schema.getFields(); 

    ArrayList<Schema.Field> new_list = new ArrayList(); 

    //create a new "empty" schema 
    //public static Schema createRecord(String name, String doc, String namespace, boolean isError) { 

    Schema s2 = Schema.createRecord("new_schema", "info", "com.namespace.test", false); 

    //add existing fields 
    for(Schema.Field f : field_list) { 

     //f.schema() here is really type "schema" like long or string, not a link back to a custom schema 
     Schema.Field ff = new Schema.Field(f.name(), f.schema(), f.doc(), f.defaultVal()); 
     new_list.add(ff); 
    } 

    //this here is just to show how to create an optional string, its a union of null and string types 
    ArrayList<Schema> optionalString = new ArrayList<>(); 
    optionalString.add(Schema.create(Schema.Type.NULL)); 
    optionalString.add(Schema.create(Schema.Type.STRING)); 

    //add the new 3 test fields in as optional string types 
    //default value here appears arbitrary, when you write the record if its not optional it doesn't //pick up default value 

    String[] sArray = {"test", "test2", "test3"}; 

    for(String s : sArray) { 

     Schema.Field f = new Schema.Field(s, Schema.createUnion(optionalString), s, "null"); 
     new_list.add(f); 
    } 

    s2.setFields(new_list); 

既存のスキーマにsetFieldsを設定することはできません。既存のスキーマが存在すると、スキーマはロックされるためです。

注意:デフォルト値に注意してください - 型が一致しない場合、すべてがうまく書かれますが、あなたはavroファイルを読むことができません!

関連する問題