如何使用AvroParquetWriter从scala case类创建一个镶木地板文件?

时间:2017-08-23 14:13:45

标签: scala avro parquet

我有一个类似下面的案例类:

case class Person(id:Int,name: String)

现在,我编写了以下方法,使用 AvroParquetWriter Seq [T] 制作镶木地板文件。

  def writeToFile[T](data: Iterable[T], schema: Schema, path: String, accessKey: String, secretKey: String): Unit = {
    val conf = new Configuration

    conf.set("fs.s3.awsAccessKeyId", accessKey)
    conf.set("fs.s3.awsSecretAccessKey", secretKey)

    val s3Path = new Path(path)
    val writer = AvroParquetWriter.builder[T](s3Path)
      .withConf(conf)
      .withSchema(schema)
      .withWriteMode(ParquetFileWriter.Mode.OVERWRITE)
      .build()
      .asInstanceOf[ParquetWriter[T]]

    data.foreach(writer.write)

    writer.close()
  }

架构是:

val schema = SchemaBuilder
    .record("Person")
      .fields()
      .requiredInt("id")
      .requiredString("name")
      .endRecord()

现在,当我用下面的代码调用writeToFile时,我得到了异常:

val personData = Seq(Person(1,"A"),Person(2,"B"))

ParquetService.writeToFile[Person](
      data = personData,
      schema = schema,
      path = s3Path,
      accessKey = accessKey,
      secretKey = secretKey
  

java.lang.ClassCastException:com.entities.Person无法强制转换为   org.apache.avro.generic.IndexedRecord

为什么无法投放到 IndexedRecord ?我还需要做些什么才能摆脱这种异常吗?

1 个答案:

答案 0 :(得分:1)

我有一个类似的问题,根据这个例子

https://github.com/apache/parquet-mr/blob/f84938441be49c665595c936ac631c3e5f171bf9/parquet-avro/src/test/java/org/apache/parquet/avro/TestReflectReadWrite.java#L141

您在编写器构建器上缺少一个方法调用。

val writer = AvroParquetWriter.builder[T](s3Path)
  .withConf(conf)
  .withSchema(schema)
  .withDataModel(ReflectData.get) //This one
  .withWriteMode(ParquetFileWriter.Mode.OVERWRITE)
  .build()

此外,如果您希望在数据中支持空值,则可以使用ReflectData.AllowNull.get()