使用反射编写POJO并将其写入Parquet文件

5

你好,我正在寻找使用我已有的POJO类来编写Parquet文件的API。 我能够使用反射生成Avro模式,然后使用AvroSchemaConverter创建Parquet模式。 但我无法找到将POJO类转换为通用记录(Avro)的方法,否则我就可以使用AvroParquetWriter将POJO类写入parquet文件了。 有什么建议吗?

3个回答

1
如果您想使用avro,有两个选项:
1)让avro生成您的pojo(请参见这里的教程)。生成的pojo扩展了SpecificRecord,可以与AvroParquetWriter一起使用。
2)手动编写从您的pojo到GenericRecord的转换。您可以手动完成此操作,或者更通用的解决方案是使用反射。但是,当我尝试读取数据时,我遇到了困难。基于提供的模式,avro在类路径中找到了pojo,并尝试实例化SpecificRecord而不是GenericRecord。因此,出于这个原因,我选择了选项1。
Parquet现在也支持直接编写pojo。这里是parquet github页面上的拉取请求。但是,我认为这还不是官方发布的一部分。换句话说,在maven中我没有找到这段代码。

谢谢您的建议,Karolovbrat。我会尝试这些方法。理想情况下,我希望能够看到拉取请求发布。我看到Parquet 2.x版本即将发布。 - Urvishsinh Mahida
您可以按照@karolovbrat所述的以下步骤来解决读取器问题:Configuration conf = new Configuration(); conf.set(AVRO_DATA_SUPPLIER, GenericDataSupplier.class.getName()); ParquetReader<GenericRecord> parquetReader = AvroParquetReader.<GenericRecord>builder(new Path(this.file.getAbsolutePath())) .withConf(conf) .build(); - harshvardhan.agr

0
免责声明:以下代码是我匆忙写的。它不高效,未来版本的parquet肯定会更直接地修复这个问题。话虽如此,这是一种轻量级低效的方法来实现你所需的功能。策略是POJO -> AVRO -> PARQUET。
1. POJO -> AVRO:通过反射声明一个模式。根据该模式声明编写器和读取器。在转换时,将对象写入字节流并以avro格式读取回来。 2. AVRO -> Parquet:使用parquet-me项目中包含的AvroParquetWriter。
private static final Schema avroSchema = ReflectData.AllowNull.get().getSchema(YOURCLASS.class);
private static final ReflectDatumWriter<YOURCLASS> reflectDatumWriter = new ReflectDatumWriter<>(avroSchema);
private static final GenericDatumReader<Object> genericRecordReader = new GenericDatumReader<>(avroSchema);

public GenericRecord toAvroGenericRecord() throws IOException {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    reflectDatumWriter.write(this, EncoderFactory.get().directBinaryEncoder(bytes, null));
    return (GenericRecord) genericRecordReader.read(null, DecoderFactory.get().binaryDecoder(bytes.toByteArray(), null));
}

还有一件事:似乎parquet写入器目前对空字段非常严格。在尝试写入parquet之前,请确保您的所有字段都不为空。


0

我没有找到现成的解决方案,所以我自己实现了一个。这是实现的链接:https://gist.github.com/alexeygrigorev/eab72e40c6051e0163a6693054906d66

简而言之,它做了以下几件事:

  • 使用反射从pojo获取Avro模式
  • 使用模式和反射将pojos转换为GenericRecord对象
  • 如果pojo包含其他pojo或pojo列表,则递归应用反射

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接