大数据-玩转数据-Spark-SQL编程基础(python版)
说明:Spark SQL是Spark用来处理结构化数据的一个模块,它将Spark SQL转换成RDD,然后提交到Spark集群执行,执行速度快,对原有Hadoop生态兼容性好。Spark-SQL所用数据抽象为DataFrame,是一种以RDD为基础的分布式数据集,相当于关系数据库的表。
启动了hdfs,yarn,zookeeper,mysql,spark
一、创建和保存DataFrame
独立应用编程时候,可以先创建一个SparkSession对象,再进行数据的读取和存储操作。
[root@hadoop1 temp]# vi sparkcreatdatafrom.py
from pyspark import SparkContext,SparkConf
from pyspark.sql import SparkSession
spark = SparkSession.builder.config(conf = SparkConf()).getOrCreate()
spark2 = spark.read.text("file:///home/hadoop/temp/word.txt")
spark2.write.text("file:///home/hadoop/temp/word")
执行查看结果
[root@hadoop1 temp]# python3 sparkcreatdatafrom.py
[root@hadoop1 temp]# ls word/
part-00000-f3ad27ad-ac8f-4913-9b0e-0a16ff59561c-c000.txt _SUCCESS
如果用pyspark,默认就已经启动了了SparkContext(名称为sc)和SparkSession对象(名称为spark),可以直接调用。
读取以下类型文件创建DataFrame:
spark.read.text(“text.txt”)
spark.read.json(“text.json”)
spark.read.parquet(text.parquet)
或换一种表达方式
spark.read.format(“text”).load(“text.txt”)
spark.read.format(“json”).load(“text.json”)
spark.read.format(“parquet”).load(“text.parquet”)
实际读取使用正确读取路径。
写入DataFrame
spark2.write.text(“text1.txt”)
spark2.write.json(“text1.json”)
spark2.write.parquet(text1.parquet)
或换一种表达方式
spark2.write.format(“text”).load(“text1.txt”)
spark2.write.format(“json”).load(“text1.json”)
spark2.write.format(“parquet”).load(“text1.parquet”)
实际写入正确存储路径。
以下是读取.json 文件,创建DataFrame然后写入.json 文件和.txt
[root@hadoop1 temp]#pyspark
>>> studentDf = spark.read.json("file:///home/hadoop/temp/student.json")
>>> studentDf.select("name","age").write.json("file:///home/hadoop/temp/studentnew3.json")
>>> studentDf.select("name").write.text("file:///home/hadoop/temp/studentnew3.txt")
注意studentnew3.json,studentnew3.txt 是目录文件,但是读取的时候可以直接用目录,便可读取下面的文件。
二、DataFrame 的常用操作
在创建了DataFrame后,可以执行对它的常用操作,比如printSchema(),select(),filter(),groupBy(),sort()
>>> studentDf = spark.read.json("file:///home/hadoop/temp/student.json")
>>> studentDf.printSchema()
显示
>>> studentDf.select("name").show()
显示
>>> studentDf.filter(studentDf["age"]>20).show()
显示
>>> studentDf.groupBy(studentDf["age"]).count().show()
显示
>>> studentDf.sort(studentDf["age"].desc()).show()
显示
三、RDD到DataFrame 的转换
文件内容
转换过程
>>> student = spark.sparkContext.textFile("file:///home/hadoop/temp/wordnameage.txt").map(lambda line:line.split(",")).map(lambda p:Row(name = p[0],age=int(p[1])))
>>> schemastudent = spark.createDataFrame(student)
>>> schemastudent.createOrReplaceTempView("student")
>>> studentDf = spark.sql("select name,age from student where age>20")
>>> studentRDD = studentDf.rdd.map(lambda p:"Name: "+p.name+ ","+"Age: " +str(p.age))
>>> studentRDD.foreach(print)
显示
四、使用Mysql数据库验证Spark-SQL的数据读写
1、准备数据库及关系表数据
[root@hadoop1 temp]# mysql -uroot -p
mysql> create database spark;
mysql> use spark
mysql> create table student(id int(4),name char(20),gender char(4),age int(4));
mysql> insert into student values('1','xiaoping','F','23');
mysql> insert into student values('1','liuyan','F','24');
mysql> select * from student;
+------+----------+--------+------+
| id | name | gender | age |
+------+----------+--------+------+
| 1 | xiaoping | F | 23 |
| 1 | liuyan | F | 24 |
+------+----------+--------+------+
2、加载mysql数据库驱动
将对应mysql jdbc驱动拷贝到Spark安装目录的jars子目录中
[root@hadoop1 jars]# cp /home/hadoop/sqoop/extra/mysql-connector-java-5.1.36.jar /home/hadoop/spark/jars/
3、读取mysql数据库中数据
确定mysql原程连接权限已经打开
>>> jdbcDf=spark.read.format("jdbc").option("driver","com.mysql.jdbc.Driver").option("url","jdbc:mysql://hadoop1:3306/spark").option("dbtable","student").option("user","root").option("password","Sunbo:123").load()
>>> jdbcDf.show()
+---+--------+------+---+
| id| name|gender|age|
+---+--------+------+---+
| 1|xiaoping| F| 23|
| 1| liuyan| F| 24|
+---+--------+------+---+
4、向mysql写入数据
[root@hadoop1 temp]# vi insertstudent.py
from pyspark.sql import Row
from pyspark.sql.types import *
from pyspark import SparkContext,SparkConf
from pyspark.sql import SparkSession
spark = SparkSession.builder.config(conf = SparkConf()).getOrCreate()
#设置模式信息
schema = StructType([StructField("id",IntegerType(),True),StructField("name",StringType(),True),StructField("gender",StringType(),True),StructField("age",IntegerType(),True)])
#设置两个学生数据
studentRDD = spark.sparkContext.parallelize(["3 zhangsan M 26","4 rongli M 32"]).map(lambda x:x.split(" "))
#创建Row对象,每个Row对象都是rowRDD中的一行
rowRDD = studentRDD.map(lambda p:Row(int(p[0].strip()),p[1].strip(),p[2].strip(),int(p[3].strip())))
#建立Row对象和模式之间的对应关系,也就是把数据和模式对应起来
studentDF = spark.createDataFrame(rowRDD,schema)
#写入数据库
url = 'jdbc:mysql://hadoop1/spark?useSSL=false'
prop = {'user': 'root', 'password': 'Sunbo:123','driver':'com.mysql.jdbc.Driver'}
studentDF.write.jdbc(url,'student','append',prop)
[root@hadoop1 temp]# python3 insertstudent.py
查看结果