在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的通用类的主要内容,如果未能解决你的问题,请参考以下文章

如何读取 CSV 文件,然后在 Spark Scala 中将其保存为 JSON?

将读取文件的架构存储到 spark scala 中的 csv 文件中

无法从 synapse spark scala notebook 读取 csv 文件

转换为 csv 文件后读取数据帧会在 Scala 中呈现不正确的数据帧

scala 如何读取 csv 文件

scala 如何读取 csv 文件