笔记二十一:Spark基础_07

SparkSQL读取数据源

# A.给定读取数据源的类型和地址
spark.read.format("json").load(path)
spark.read.format("csv").load(path)
spark.read.format("parquet").load(path)
# B.直接调用对应数据源类型的方法
spark.read.json(path)
spark.read.csv(path)
spark.read.parquet(path)
# 特殊参数:option,用于指定读取或输出时的一些配置选项
# option("sep", "\t")指定分隔符
spark.read.format("csv").option("sep", "\t").load(path)

jdbcDF = spark.read \
    .format("jdbc") \
    .option("url", "jdbc:postgresql:dbserver") \
    .option("dbtable", "schema.tablename") \
    .option("user", "username") \
    .option("password", "password") \
    .load()

df.write \
.format("jdbc") \
.option("url", "jdbc:postgresql:dbserver") \
.option("dbtable", "schema.tablename") \
.option("user", "username") \
.option("password", "password") \
.save()

SparkSQL写出数据源

# a.给定输出数据源的类型和地址
df.write.format("json").save(path)
df.write.format("csv").save(path)
df.write.format("parquet").save(path)
# b.直接调用对应数据源类型的方法
df.write.json(path)
df.write.csv(path)
df.write.parquet(path)
# c.Save Mode
# 保存时指定怎么将数据写入目标数据源
df.write.mode(saveMode="append").format("csv").save(path)

# mode
append: 追加模式,当数据存在时,继续追加
overwrite: 覆写模式,当数据存在时,覆写以前数据,存储当前最新数据;
error/errorifexists: 如果目标存在就报错,默认的模式
ignore: 忽略,数据存在时不做任何操作

SparkSQL的UDF

# UDF,User Define Function,用户自定义函数

#1.定义一个普通的Python函数

#2.把Python函数注册到Spark中,注册方式有三种
(1)spark.udf.register(3个参数)
(2)F.udf(2个参数)
(3)@F.udf(1个参数)

 案例

读写csv文件

# 读取
# 逗号分隔的文件
csv_df1 = spark.read.csv("../data/resources/people.txt")
csv_df1.printSchema()
csv_df1.show()

# 分号作为分隔的文件
csv_df2 = spark.read.format("csv").option("sep", ";").load("../data/resources/people.csv")
csv_df2.printSchema()
csv_df2.show()

# 制表符作为分隔符sep,以第一行的内容作为列名header,自动推断类型inferSchema
csv_df3 = spark.read.format("csv")\
                .option("sep", "\t")\
                .option("header", "true")\
                .option("inferSchema", "true")\
                .load("../data/resources/people.tsv")
csv_df3.printSchema()
csv_df3.show()



# 输出
csv_df1.write.csv("../data/output/csv/csv01")
csv_df2.write.format("csv").save(path="../data/output/csv/csv02")
csv_df3.write\
    .mode("overwrite")\
    .format("csv")\
    .option("sep", "\t")\
    .save(path="../data/output/csv/csv03")

读写json文件

# 读取
json_df1 = spark.read.json(path="../data/output/people.json")
json_df1.printSchema()
json_df1.show()

json_df2 = spark.read.format("json").load(path="../data/output/people.json")
json_df2.printSchema()
json_df2.show()

json_df3 = spark.read.format("json").option("path", "../datas/output/people.json").load()
json_df3.printSchema()
json_df3.show()


# 写出
json_df1.write.json(path="../data/output/json/json01")
json_df2.write.format("json").save(path="../data/output/json/json02")
json_df3.write\
		.mode("overwrite")\
		.format("json")\
		.option("path", "../data/output/json/json03")\
		.save()

 UDF自定义函数

from pyspark.sql import SparkSession
import os

from pyspark.sql.types import StringType
import pyspark.sql.functions as F

# 1.构建SparkSession
# 建造者模式:类名.builder.配置…….getOrCreate()
# 自动帮你构建一个SparkConf对象,只要指定你需要哪些配置就可
spark = SparkSession \
    .builder \
    .master("local[2]") \
    .appName("SparkSQLAppName") \
    .config("spark.sql.shuffle.partitions", 4) \
    .getOrCreate()

# 2.数据输入
input_df = spark.read.csv(path='../data/people.txt',
schema='name string, age int',sep=', ')

# 3.数据处理:把name字段后拼接一个"_itcast"
#自定义Python函数
#参数一:返回值类型
@F.udf(returnType=StringType())
def concat_name(name):
    return name + "_itcast"
#register的三个参数:
#参数一:SQL中可以使用的自定义函数,只能在SQL用
#参数二:需要把那个Python函数注册到Spark中
#参数三:返回值类型,这是Java类型LongType(),IntegerType()

#concat_name_dsl1 = spark.udf.register(name="concat_name_sql",f=concat_name,
returnType=StringType())

#udf的两个参数:只能用于DSL
#参数一:自定义的Python函数
#参数二:返回值类型
#concat_name_dsl2 = F.udf(f=concat_name,returnType=StringType())



#3.1 SQL
input_df.createOrReplaceTempView("t1")
#result_df1 = spark.sql("select name,age,concat_name_sql(name) as concatName from t1")

#3.2 DSL
#result_df2 = input_df.select(input_df['name'],input_df['age'],
concat_name_dsl1(input_df['name']).alias('concatName_DSL1'))

#result_df3 = input_df.select(input_df['name'],input_df['age'],
concat_name_dsl2(input_df['name']).alias('concatName_DSL2'))

result_df4 = input_df.select(input_df['name'],input_df['age'],
concat_name(input_df['name']).alias('concatName_DSL3'))


# 4.数据输出
#input_df.printSchema()
#input_df.show()
#result_df1.show()
#result_df2.show()
#result_df3.show()
result_df4.show()
# 5.关闭SparkSession
spark.stop()
# PySpark的UDF实现
(1)注册方式一:spark.udf.register("sql中的函数",python自定义函数,返回值类型),
结果可以接收。接收后的结果可以在SQL或者DSL中使用。

(2)注册方式二:F.udf(Python自定义函数,返回值类型),结果可以接收,
接收后的结果只能在DSL中使用。

(3)注册方式三:在Python自定义函数上面,直接@F.udf(返回值类型),
本质上是Python装饰器。接收后的结果只能在DSL中,且函数名就是Python的函数名。

调优

SQL语句中的【group by】、【order by】,【distinct】关键字都会触发shuffle
触发shuffle的并行度参数【spark.sql.shuffle.partitions】,参数默认是【200】
可以适时降低,建议申请为CPU核数的2~3倍

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值