【问题标题】:Complex in memory object to Parquet files without Apache Spark没有 Apache Spark 的 Parquet 文件的内存对象复杂
【发布时间】:2018-03-10 11:30:00
【问题描述】:

我有一个对象,我想为这些列表中的每一个创建一个镶木地板文件。 该对象如下所示:

case class ProgramsData(programs: List[Program], switches: List[Switch], paths: List[Path],
                    activities: List[Activity], enactments: List[Enactment])

经过一番研究,我对如何实现这一点感到有些困惑。

似乎没有 Apache Spark 的唯一方法是将您的对象转换为 Avro 文件,然后将其读入并获取架构,然后您可以从中创建 parquet 文件。

有没有办法去掉中间人并将我的对象转换为对象内每个列表的镶木地板文件? 如果没有,实现我的最终目标的最简单方法是什么? 遗憾的是,我看到的少数几个例子中的大多数要么不起作用,要么没有完全按照我的意愿行事。

提前致谢。

编辑 因此,经过一整天的工作后,我生成了一些生成文件的代码。但是在编写一些代码以读取镶木地板文件时,它告诉我它无法解码。这告诉我编写器代码是错误的(尽管如果它不能创建有效的 parquet 文件,它肯定会抛出异常?)

这里是编写代码:

val avroSchema: Schema = ReflectData.get().getSchema(classOf[Program])

  val parquetOutputPath = new org.apache.hadoop.fs.Path(outputFilePath)

  val parquetWriter = new AvroParquetWriter[Record](parquetOutputPath, avroSchema)

  programs.foreach(program => {
    val programRecord = new GenericData.Record(avroSchema)
    programRecord.put("name", program.getName)

    parquetWriter.write(programRecord)
  })

  parquetWriter.close()

这里是阅读代码:

 val avroSchema: Schema = ReflectData.get().getSchema(classOf[Program])

val filePath = new org.apache.hadoop.fs.Path(filePathString)

val parquetReader = new AvroParquetReader[Record](filePath)

val record = parquetReader.read()

读取代码最后一行抛出如下异常:

.ParquetDecodingException: 无法读取文件 file:/tmp/parquet/test-1506962769.parquet 中块 0 中 1 处的值

希望有人能指出正确的方向,否则我可能不得不使用 Apache Spark,因为它能够轻松创建 parquet 文件,这有点过头了。

【问题讨论】:

    标签: java scala avro parquet


    【解决方案1】:

    您可以使用 avro 架构编写 parquet 文件,而无需使用 spark。

    这里是一个 java 中的示例代码,它将 parquet 格式写入本地磁盘。

    {
    final String schemaLocation = "/tmp/avro_format.json";
    final Schema avroSchema = new Schema.Parser().parse(new File(schemaLocation));
    final MessageType parquetSchema = new AvroSchemaConverter().convert(avroSchema);
    final WriteSupport<Pojo> writeSupport = new AvroWriteSupport(parquetSchema, avroSchema);
    final String parquetFile = "/tmp/parquet/data.parquet";
    final Path path = new Path(parquetFile);
    ParquetWriter<GenericRecord> parquetWriter = new ParquetWriter(path, writeSupport, CompressionCodecName.SNAPPY, BLOCK_SIZE, PAGE_SIZE);
    final GenericRecord record = new GenericData.Record(avroSchema);
    record.put("id", 1);
    record.put("age", 10);
    record.put("name", "ABC");
    record.put("place", "BCD");
    parquetWriter.write(record);
    parquetWriter.close();
    }
    

    avro_format.json,

    {
       "type":"record",
       "name":"Pojo",
       "namespace":"com.xx.test",
       "fields":[
          {
             "name":"id",
             "type":[
                "int",
                "null"
             ]
          },
          {
             "name":"age",
             "type":[
                "int",
                "null"
             ]
          },
          {
             "name":"name",
             "type":[
                "string",
                "null"
             ]
          },
          {
             "name":"place",
             "type":[
                "string",
                "null"
             ]
          }
       ]
    }
    

    希望这会有所帮助。

    【讨论】:

    • 创建镶木地板编写器的行无法为我编译。它无法解析构造函数。
    • 你的 Pojo 课程是什么样的?它是否扩展了 IndexedRecord?
    • 1. import org.apache.parquet.hadoop.ParquetWriter 2. pojo是一个普通的java类,它没有扩展IndexedRecord
    【解决方案2】:

    是的,您可以直接执行此操作。 Refer

    您可以从这里了解如何将数据写入镶木地板。它以字符串为例。 为更多不同类型的列编写。首先我们必须给出我们在 MessageType 中解释的模式。

    【讨论】:

    • 我有点困惑,有没有与你链接的代码类似的代码示例?
    • 我试过了,但什么也没找到。几天前我也有同样的问题。所以我试图理解这一点只是为了写更多的专栏。
    猜你喜欢
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 2020-07-28
    • 2017-09-06
    • 2015-10-28
    • 1970-01-01
    相关资源
    最近更新 更多