Spark(21) — Spark SQL — DataFrame创建(scala版)

1. 读取文本文件创建DataFrame

?在spark2.0版本之前,Spark SQL中SQLContext是创建DataFrame和执行SQL的入口,可以利用hiveContext通过hive sql语句操作hive表数据,兼容hive操作,并且hiveContext继承自SQLContext。在spark2.0之后,这些都统一于SparkSession,SparkSession 封装了 SparkContext,SqlContext,通过SparkSession可以获取到SparkConetxt,SqlContext对象。
在这里插入图片描述
构建DF有两种方式

1.1 第一种方式:通过RDD配合case class进行转换DF

  1. 第一步:创建文本文件
    在linux的/export/servers/路径下创建文本文件
1
2
cd /export/servers/
vim person.txt

写入文件:

1
2
3
4
5
6
1 zhangsan 20
2 lisi 29
3 wangwu 25
4 zhaoliu 30
5 tianqi 35
6 kobe 40
  1. 第二步:定义RDD
    使用spark-shell 进入spark客户端
1
2
3
cd /export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/
bin/spark-shell --master local[2]
val lineRDD = sc.textFile("file:///export/servers/person.txt").map(x => x.split(" "))
  1. 第三步:定义case class样例类
1
case class Person(id:Int,name:String,age:Int)
  1. 第四步:关联RDD与case class
1
val personRDD = lineRDD.map(x => Person(x(0).toInt,x(1),x(2).toInt))

  1. 第五步:将RDD转换成DF
1
val personDF  = personRDD.toDF

注意:DF也可以转换成为RDD,直接使用DF调用rdd方法即可

1
2
scala> personDF.rdd.collect
res38: Array[org.apache.spark.sql.Row] = Array([1,zhangsan,20], [2,lisi,29], [3,wangwu,25], [4,zhaoliu,30], [5,tianqi,35], [6,kobe,40])

case class 反射创建
在这里插入图片描述
直接使用toDF方法 - 不能保证字段类型(常用的还是case class 反射创建)
在这里插入图片描述

1.2 第二种方式:通过sparkSession构建DataFrame

1
val personDF2 = spark.read.text("file:///export/servers/person.txt")

输出:
在这里插入图片描述
直接使用SparkSession创建 - (结果没有拆分开,还得继续拆分)
在这里插入图片描述

2. 读取json文件创建DataFrame

spark给我们提供了json格式的示例文件,路径在

1
/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json

我们可以直接通过spark解析json数据进行创建DF

1
val jsonDF = spark.read.json("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/people.json")

读取json的两种方法:
在这里插入图片描述
在这里插入图片描述

3. 读取parquet列式存储格式文件创建DataFrame

spark也给我们提供了parquet格式的数据,我们也可以通过spark直接解析parquet格式的数据来进行创建DF,示例文件的路径在

1
/export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/users.parquet

1
val parquetDF = spark.read.parquet("file:///export/servers/spark-2.2.0-bin-2.6.0-cdh5.14.0/examples/src/main/resources/users.parquet")

4. 读取CSV的数据集

以逗号分隔的文本文件,IEDA写代码演示该部分,比较重要

1
2
spark.read.csv(path)
spark.read.format("csv").load(path)

5. 代码演示

  1. 使用caseclass的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import org.apache.spark.rdd.RDD
import org.apache.spark.{<!-- -->SparkConf, SparkContext}
import org.apache.spark.sql.{<!-- -->DataFrame, SparkSession}

/**
 * DESC:这里创建SparkSession,因为这里需要使用SparkSQL的模块
 * 在Spark2.0中已经将SQLContext,HIveContext和SparkCOntext都进行封装直接使用
 * 1-创建SparkSession的环境
 * 2-读取本地的文件
 * 3-定义样例类
 * 4-使用map方法对rdd进行转换,在通过toDF转化为DF
 * 5-可以查看DF
 * 6-查看Schema信息
 * 7-关闭资源
 */
case class people2(id: Int, name: String, age: Double)

object _01SparkCreateDataFrame {<!-- -->
  def main(args: Array[String]): Unit = {<!-- -->
    //* 1-创建SparkSession的环境
    val conf: SparkConf = new SparkConf().setAppName("_01SparkCreateDataFrame").setMaster("local[*]")
    val spark: SparkSession = SparkSession.builder().config(conf).getOrCreate()
    //能否使用Spark创建sparkContext
    val sc: SparkContext = spark.sparkContext
    sc.setLogLevel("WARN")
    //在SparkSQL中如果从RDD转化为DataFrame中需要引入隐式转换
    import spark.implicits._
    //* 2-读取本地的文件
    val fileRDD: RDD[String] = sc.textFile("./datasets/input/people2.txt")
    //fileRDD.collect().foreach(println(_))
    //* 3-定义样例类--上述
    //* 4-使用map方法对rdd进行转换,在通过toDF转化为DF
    val people2DF: DataFrame = fileRDD.map(_.split(" ")).map(item => people2(item(0).toInt, item(1), item(2).toDouble)).toDF()
    //* 5-可以查看DF
    people2DF.show()
    /* +---+--------+----+
     | id|    name| age|
     +---+--------+----+
     |  1|zhangsan|20.0|
       |  2|    lisi|29.0|
       |  3|  wangwu|25.0|
       |  4| zhaoliu|30.0|
       |  5|  tianqi|35.0|
       +---+--------+----+*/
    //* 6-查看Schema信息
    people2DF.printSchema()
    /*    root
        |-- id: integer (nullable = false)
        |-- name: string (nullable = true)
        |-- age: double (nullable = false)*/
    //* 7-关闭资源
    spark.close()
  }
}
  1. 直接使用TODF的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{<!-- -->DataFrame, SparkSession}
import org.apache.spark.{<!-- -->SparkConf, SparkContext}

/**
 * DESC:这里创建SparkSession,因为这里需要使用SparkSQL的模块
 * 在Spark2.0中已经将SQLContext,HIveContext和SparkCOntext都进行封装直接使用
 * 1-创建SparkSession的环境
 * 2-读取本地的文件
 * 3-定义样例类
 * 4-使用map方法对rdd进行转换,在通过toDF转化为DF
 * 5-可以查看DF
 * 6-查看Schema信息
 * 7-关闭资源
 */
object _02SparkCreateDataFrame {<!-- -->
  def main(args: Array[String]): Unit = {<!-- -->
    //* 1-创建SparkSession的环境
    val conf: SparkConf = new SparkConf().setAppName("_02SparkCreateDataFrame").setMaster("local[*]")
    val spark: SparkSession = SparkSession.builder().config(conf).getOrCreate()
    //能否使用Spark创建sparkContext
    val sc: SparkContext = spark.sparkContext
    sc.setLogLevel("WARN")
    //在SparkSQL中如果从RDD转化为DataFrame中需要引入隐式转换

    import spark.implicits._

    //* 2-读取本地的文件
    val fileRDD: RDD[String] = sc.textFile("./datasets/input/people2.txt")
    //fileRDD.collect().foreach(println(_))
    //* 3-定义样例类--上述
    //* 4-使用map方法对rdd进行转换,在通过toDF转化为DF
    val people2DF: DataFrame = fileRDD.map(_.split(" ")).map(item => (item(0).toInt, item(1), item(2).toDouble)).toDF("id","name","age")
    //* 5-可以查看DF
    people2DF.show()
    /* +---+--------+----+
     | id|    name| age|
     +---+--------+----+
     |  1|zhangsan|20.0|
       |  2|    lisi|29.0|
       |  3|  wangwu|25.0|
       |  4| zhaoliu|30.0|
       |  5|  tianqi|35.0|
       +---+--------+----+*/
    //* 6-查看Schema信息
    people2DF.printSchema()
    /*    root
        |-- id: integer (nullable = false)
        |-- name: string (nullable = true)
        |-- age: double (nullable = false)*/
    //* 7-关闭资源
    spark.close()
  }
}
  1. 使用外部的Json的格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import org.apache.spark.sql.{<!-- -->DataFrame, SparkSession}

/**
 * DESC:
 * 1-准备SparkSession环境
 * 2-读取Json文件
 * 3-查看Json的内容
 * 4-查看Json的schema的信息
 * 5-关闭资源
 */
object _03SparkCreateDataFrameJson {<!-- -->
  def main(args: Array[String]): Unit = {<!-- -->
    //1-准备SparkSession环境
    val spark: SparkSession = SparkSession.builder().appName("_03SparkCreateDataFrameJson").master("local[*]").getOrCreate()
    spark.sparkContext.setLogLevel("WARN")
    //2-读取Json文件
    val peopleDF: DataFrame = spark.read.json("./datasets/input/people.json")
    //方法2
    val df2: DataFrame = spark.read.format("json").load("./datasets/input/people.json")
    //3-查看Json的内容
    peopleDF.show(truncate = false, numRows = 20)
    peopleDF.show(truncate = false)
    peopleDF.show(20)
    peopleDF.show(numRows = 20)
    df2.show()
    //4-查看Json的schema的信息
    peopleDF.printSchema()
    //5-关闭资源
    spark.stop()
  }
}