[英]how to created REPEATED type in parquet file schema with avro?
我們正在創建一個數據流管道,我們將從postgres中讀取數據並將其寫入一個Parquet文件中。 ParquetIO.Sink允許您將GenericRecord的PCollection寫入Parquet文件(來自此處https://beam.apache.org/releases/javadoc/2.5.0/org/apache/beam/sdk/io/parquet/ParquetIO。 html )。 但是實木復合地板文件架構不符合我的預期
這是我的架構:
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 group someArray (LIST) {
repeated binary array (UTF8);
}
}
這是我所期望的:
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語言規范中, optional repeated
操作沒有意義: https : //developers.google.com/protocol-buffers/docs/reference/proto2-spec
您可以刪除null
括號和方括號以生成簡單的repeated
字段,並且在語義上等效於optional repeated
字段(因為repeated
表示零次或多次)。
我沒有找到一種方法來從Avro中創建一個不在GroupType中的重復元素。
Beam中的ParquetIO使用parquet-mr
項目中定義的“標准” avro轉換,在此處實現。
似乎有兩種方法可以將Avro ARRAY字段轉換為Parquet消息-但這兩種都不創建您要查找的內容。
當前,avro轉換是目前與ParquetIO交互的唯一方法。 我在ParquetIO中看到了這個JIRA Use Beam模式,該模式將其擴展到Beam Rows,這可能允許使用不同的Parquet消息策略。
或者,您可以為ParquetIO創建JIRA功能請求以支持節儉結構,這應該允許對Parquet結構進行更好的控制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.