使用反射将pojo写入parquet文件

qni6mghb  于 2021-06-02  发布在  Hadoop
关注(0)|答案(3)|浏览(469)

嗨,寻找API编写与我有波乔谈判。我能够使用反射生成avro模式,然后使用avroschemaconverter创建Parquet模式。另外,我也找不到一种方法来转换pojo到genericrecords(avro),否则我就可以使用avroparquetwriter将pojo写入parquet文件。有什么建议吗?

unftdfkk

unftdfkk1#

免责声明:以下代码是在我很匆忙的时候编写的。这是没有效率的,未来版本的Parquet肯定会解决这个更直接。也就是说,这是一个轻量级的低效的方法来满足您的需要。策略是pojo->avro->parquet
pojo->avro:通过反射声明模式。基于架构声明编写器和读取器。在转换时,将对象写入字节流并作为avro读回。
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之前,请确保没有任何字段为null

l7wslrjt

l7wslrjt2#

我无法找到现有的解决方案,所以我自己实现了它。以下是实现的链接:https://gist.github.com/alexeygrigorev/eab72e40c6051e0163a6693054906d66
简而言之,它执行以下操作:
使用反射从pojo获取avro模式
使用模式和反射将pojo转换为 GenericRecord 物体
如果pojo包含其他pojo或pojo列表,则递归应用反射

w8f9ii69

w8f9ii693#

如果你想通过avro,你有两个选择:
1) 让avro生成pojo(参见这里的教程)。生成的pojo extend specificrecord可以与avroparquetwriter一起使用。
2) 写下从pojo到genericord的转换。您可以手动执行此操作,或者更通用的解决方案是使用反射。然而,当我试图读取数据时,我遇到了这种方法的困难。基于提供的模式,avro在类路径中找到了pojo,并尝试示例化specificrerd而不是genericrecord。因为这个原因,我选择了选项1。
parquet现在还支持直接编写pojo。这是Parquetgithub页面上的pull请求。不过,我认为这还不是官方发布的一部分。换句话说,我在maven中没有找到这段代码。

相关问题