在scala中读取csv的通用类

Posted

技术标签:

【中文标题】在scala中读取csv的通用类【英文标题】:Generic class to read csv in scala 【发布时间】:2018-11-05 21:21:18 【问题描述】:

我是 Scala 的新手,我正在尝试构建一个可以读取多种类型的 csv 文件的框架,并且所有读取操作都将通过一个类。例如,我有两种类型的 CSV:StudentProfessor,我正在做这样的事情。

abstract class Person
case class Student(name: String, major: String, marks: Double) extends Person
case class Professor(name: String, salary: Double) extends Person

我的 csv 阅读器看起来像这样

  private def readCsv[T: Encoder](location: String) = 
    spark
      .read
      .option("header", "true")
      .option("inferSchema", "true")
      .option("delimiter", ";")
      .csv(location)
      .as[T]
  

def data:Dataset[Person](location) = readCsv[Person](location)

最后一行出现编译时错误No implicit arguments of Type: Encoder[Person]。对该方法的调用如下所示:

val studentData = storage.data[Student]("Student.csv")

有没有更好的方法来实现这一点?

【问题讨论】:

错误告诉您需要提供隐式参数。您可以通过三种方式执行此操作:(1) 通过在范围内定义 implicit val,或 (2) 通过定义 implicit class,或 (3) 通过在辅助参数列表中显式传递缺少的 Encoder 参数。 当您遇到错误时,如果您在问题中包含错误和任何相关的堆栈跟踪,将会很有帮助。有关如何编写好问题的更多建议,请参阅:***.com/help/how-to-ask 我在def data:Dataset[Person](location) = readCsv[Person](location) 行收到编译时错误No implicit arguments of Type: Encoder[Person] 似乎相关 - ***.com/a/41082540/864369 和 ***.com/a/32454596/864369 【参考方案1】:
    您的 ADT 定义可能应该是最终的/密封的,否则很难为它派生 Encoders。 遗憾的是,IIRC Spark 不支持 Sum 类型,因为它没有模式表示。一个比较常见的技巧是将Either[A, B] 表示为(Option[A], Option[B]),但是是的,这很痛苦

【讨论】:

以上是关于在scala中读取csv的通用类的主要内容,如果未能解决你的问题,请参考以下文章