DataFrameReader 用于通过外部数据源的格式(如 text、CVS 等)和数据结构加载 Dataset,DataFrameReader 还提供了非常丰富的操作 DataFrame 的 API。有了DataFrame-Reader,我们就可以将各种格式的数据源转换为 Dataset 或DataFrame,进而以面向关系型数据的方式操纵各种格式的数据。
DataFrameReader属性
- source:输入数据源的格式。可通过 spark.sql.sources.default 属性配置,默认为 parquet。
小贴士:Apache Parquet 是 Hadoop 生态圈中一种新型列式存储格式,它可以兼容 Hadoop 生态圈中大多数计算框架(Hadoop、Spark 等),被多种查询引擎支持(Hive、Impala、Drill 等),并且是数据处理框架、数据模型和语言无关的。Parquet 最初是由 Twitter 和 Cloudera(由于 Impala 的缘故)合作开发完成并开源,2015 年 5 月从 Apache 的孵化器里毕业成为 Apache 顶级项目。
- userSpecifiedSchema:用户指定的 Schema,实际的类型是 StructType。
- extraOptions:类型为 HashMap[String,String],用于保存额外的选项。
DataFrameReader方法
format
用于设置输入数据源的格式
def format(source: String): DataFrameReader = {
this.source = source
this
}
schema
用于设置用户指定的结构类型(StructType)。
def schema(schema: StructType): DataFrameReader = {
this.userSpecifiedSchema = Option(schema)
this
}
多种多样的 option
DataFrameReader 提供了多个重载的 option 方法,用于向 extraOptions 中添加选项。无论哪个 option 方法,都将转换为对最基本的 option 方法的调用。
def option(key: String, value: String): DataFrameReader = {
this.extraOptions += (key -> value)
this
}
DataFrameReader 还提供了很多将其他基本类型转换为字符串后添加到 options 中的方法,例如,将长整型转换为字符串后放入 extraOptions 的 option 方法。
def option(key: String, value: Long): DataFrameReader = option(key, value.toString)
DataFrameReader 还提供了将 scala.collection.Map 或 java.util.Map 中的 key 和 value 作为选项添加到 options 中的方法,例如,将 scala.collection.Map 中的键值对放入 extraOptions 的 option 方法。
def options(options: scala.collection.Map[String, String]): DataFrameReader = {
this.extraOptions ++= options
this
}
多种多样的 load
DataFrameReader 提供了多个重载的 load 方法,用于将数据源的数据加载到DataFrame。这些 load 方法实际都会转换为调用代码清单所示的 load 方法来加载数据。
@scala.annotation.varargs
def load(paths: String*): DataFrame = {
sparkSession.baseRelationToDataFrame(
DataSource.apply(
sparkSession,
paths = paths,
userSpecifiedSchema = userSpecifiedSchema,
className = source,
options = extraOptions.toMap).resolveRelation())
}
DataFrameReader 的 load 方法首先构造 DataSource 实例,然后调用 DataSource 的 resolveRelation 方法解析得到BaseRelation,最后调用 SparkSession 的 baseRelationToDataFrame 方法将 BaseRelation 转换为 DataFrame。
重载的 text
DataFrameReader 提供了两个重载的 text 方法,用于设置输入数据源的格式为 text 并加载数据,如代码所示。
def text(path: String): DataFrame = {
text(Seq(path): _*)
}
@scala.annotation.varargs
def text(paths: String*): DataFrame = format("text").load(paths : _*)
除了 text 方法外,DataFrameReader 还提供了多个重载的 jdbc 方法、json 方法、csv 方法、parquet 方法及 orc 方法,这些方法的实现都与 text 类似,即最终落实到对 format 方法和 load 方法的调用并转换为 DataFrame。
重载的 textFile
DataFrameReader 提供了两个重载的 textFile 方法,用于设置输入数据源的格式并加载数据,如代码所示。
def textFile(path: String): Dataset[String] = {
textFile(Seq(path): _*)
}
@scala.annotation.varargs
def textFile(paths: String*): Dataset[String] = {
if (userSpecifiedSchema.nonEmpty) {
throw new AnalysisException("User specified schema not supported with `textFile`")
}
text(paths : _*).select("value").as[String](sparkSession.implicits.newString-Encoder)
}
可以看到,textFile 方法首先调用 text 方法将文本文件转换为 DataFrame,然后调用 DataFrame 的 select 方法进行选择(投影)操作。