Java 如何使用avro在拼花文件模式中创建重复类型?

Java 如何使用avro在拼花文件模式中创建重复类型?,java,google-cloud-dataflow,avro,apache-beam,parquet,Java,Google Cloud Dataflow,Avro,Apache Beam,Parquet,我们正在创建一个数据流管道,我们将从postgres读取数据并将其写入拼花文件。Sink允许您从这里将GenericRecord的PCCollection写入拼花文件。但是拼花文件模式与我预期的不同 这是我的模式: schema = new org.apache.avro.Schema.Parser().parse("{\n" + " \"type\": \"record\",\n" + " \"namespace\": \"com.examp

我们正在创建一个数据流管道,我们将从postgres读取数据并将其写入拼花文件。Sink允许您从这里将GenericRecord的PCCollection写入拼花文件。但是拼花文件模式与我预期的不同

这是我的模式:

schema = new org.apache.avro.Schema.Parser().parse("{\n" +
         "     \"type\": \"record\",\n" +
         "     \"namespace\": \"com.example\",\n" +
         "     \"name\": \"Patterns\",\n" +
         "     \"fields\": [\n" +
         "       { \"name\": \"id\", \"type\": \"string\" },\n" +
         "       { \"name\": \"name\", \"type\": \"string\" },\n" +
         "       { \"name\": \"createdAt\", \"type\": {\"type\":\"string\",\"logicalType\":\"timestamps-millis\"} },\n" +
         "       { \"name\": \"updatedAt\", \"type\": {\"type\":\"string\",\"logicalType\":\"timestamps-millis\"} },\n" +
         "       { \"name\": \"steps\", \"type\": [\"null\",{\"type\":\"array\",\"items\":{\"type\":\"string\",\"name\":\"json\"}}] },\n" +
         "     ]\n" +
         "}");
这是我目前的代码:

Pipeline p = Pipeline.create(
        PipelineOptionsFactory.fromArgs(args).withValidation().create());

p.apply(JdbcIO.<GenericRecord> read()
       .withDataSourceConfiguration(JdbcIO.DataSourceConfiguration.create(
             "org.postgresql.Driver", "jdbc:postgresql://localhost:port/database")
             .withUsername("username")
             .withPassword("password"))
       .withQuery("select * from table limit(10)")
       .withCoder(AvroCoder.of(schema))
       .withRowMapper((JdbcIO.RowMapper<GenericRecord>) resultSet -> {
            GenericRecord record = new GenericData.Record(schema);
            ResultSetMetaData metadata = resultSet.getMetaData();
            int columnsNumber = metadata.getColumnCount();
            for(int i=0; i<columnsNumber; i++) {
                Object columnValue = resultSet.getObject(i+1);
                if(columnValue instanceof UUID) columnValue=columnValue.toString();
                if(columnValue instanceof Timestamp) columnValue=columnValue.toString();
                if(columnValue instanceof PgArray) {
                    Object[] array = (Object[]) ((PgArray) columnValue).getArray();
                    List list=new ArrayList();
                    for (Object d : array) {
                        if(d instanceof PGobject) {
                            list.add(((PGobject) d).getValue());
                        }
                    }
                    columnValue = list;
                 }
                 record.put(i, columnValue);
            }
            return record;
        }))
  .apply(FileIO.<GenericRecord>write()
        .via(ParquetIO.sink(schema).withCompressionCodec(CompressionCodecName.SNAPPY))
        .to("something.parquet")
  );

p.run();
这就是我所期望的:

message com.example.table {
  required binary id (UTF8);
  required binary name (UTF8);  
  required binary createdAt (UTF8);
  required binary updatedAt (UTF8);
  optional repeated binary someArray(UTF8);
}


请帮助

这是您用来描述预期模式的protobuf消息吗?我认为您得到的是从指定的JSON模式正确生成的。可选重复在protobuf语言规范中没有意义:


您可以删除空括号和方括号以生成简单重复字段,它在语义上等同于可选重复字段,因为重复意味着零次或多次。

我没有找到从Avro创建不在GroupType中的重复元素的方法

梁中的镶木使用镶木mr项目中定义的标准avro转换,该项目已实施

似乎有两种方法可以将Avro数组字段转换为拼花信息,但这两种方法都不能创建您要查找的内容

目前,avro转换是目前与ParquetIO互动的唯一方式。我看到这个JIRA将其扩展到梁行,这可能允许使用不同的拼花信息策略

或者,您可以为ParquetIO创建JIRA功能请求以支持节俭结构,这将允许对parquet结构进行更精细的控制

message com.example.table {
  required binary id (UTF8);
  required binary name (UTF8);  
  required binary createdAt (UTF8);
  required binary updatedAt (UTF8);
  optional repeated binary someArray(UTF8);
}