达梦DM8数据库—数据中台系统学习开发记录(三)
一、数据治理具体实现
1.使用IDEA工具编写Scala代码(本地测试)
分析:利用DataFrame获取数据后,进行一系列的操作,如去重过滤等,以便达到数据治理的要求。
- 数据标准化:对数据进行命名、分类、定义和格式的标准化,确保数据的一致性和可重用性。
- 数据质量管理:对数据进行全面的质量检测和评估,发现并修正数据质量问题,提高数据的准确性和可信度。把异常数据输出到质量库,以供用户后期查询或修改。
(1) 对于身份证号的处理
①对用户数据各项数据完全一致的去重
②过滤掉数据为空NULL的行
③判断身份证号码是否够18位,进行一定的过滤
④判断身份证号码中是否有不合规的数据,如出生年份大于2023年等
(2) 物流单规则,物流信息里客户必须在客户数据中
①过滤物流信息2022.csv文件中的客户名称不在users.csv文件的客户名称中的数据
(3) 异常数据
①异常数据1 客户编号位数不为18位的
②异常数据2 客户数据有空值的
③异常数据3 客户编号中的出生年份在2023年之后的
④异常数据4 物流信息2022.csv文件中的客户名称不在users.csv文件的客户名称中的数据
import org.apache.spark.sql.{DataFrame, SparkSession, functions}
import org.apache.spark.sql.functions._
import org.apache.spark.sql.functions.{col, substring}
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}
import scala.collection.mutable.ListBuffer
object IdCard {
def main(args: Array[String]): Unit = {
// 数据治理 1.身份证号治理 身份证号主要存在users2022.csv文件中,客户编号即客户身份证号
//创建SparkSession连接
val spark = SparkSession.builder()
.master("local")
.appName("IdCard")
.getOrCreate()
//读取users.csv文件数据
val df1:DataFrame = spark
.read
.option("seq",",") // 以“,”位分隔符分割
.option("header","true") //是否将第一行作为表头
.option("charset", "utf-8") // 指定字符编码格式为 utf-8
.format("csv") //文件位csv格式
.load("input/mysql/users2022.csv") //后期换为hdfs地址
// (1)对用户数据各项数据完全一致的去重
val df2 = df1.dropDuplicates("客户编号")
// (2)过滤掉数据为空NULL的行
val dfNull = df2.na.drop()
// (3)判断身份证号码是否够18位,进行一定的过滤
val df18 = dfNull.filter(length(col("客户编号"))===18)
// (4)判断身份证号码中是否有不合规的数据,如出生年份大于2023年等
// 使用 substring 函数获取身份证号码的第7位到第10位
val idCardYear = substring(col("客户编号"), 7, 4)
// 将身份证年份转换成整数进行比较
val filteredDf = df18.filter(idCardYear.cast("int") <= 2023)
//查看过滤后的数据
//filteredDf.show()
//TODO 过滤后的数据存储
//filteredDf.coalesce(1).write.csv("output/finish1")
// (5)找到掉身份证号相同的行
// val sameId = filteredDf.groupBy("客户编号")
// .agg(functions.collect_set("客户名称").as("客户名称"),
// functions.collect_set("手机号").as("手机号"),
// functions.collect_set("省市区").as("省市区"),
// functions.count("*").as("count"))
// .where("count > 1")
// sameId.show(10)
//TODO 存储相同的身份证号码数据
//sameId.coalesce(1).write.csv("output/same")
// 数据治理 2.物流单规则,物流信息里客户必须在客户数据中
val schema = StructType(Array(
StructField("提单号", StringType),
StructField("客户名称", StringType), // 将字段重命名统一为 ”客户名称 “
StructField("货主代码", StringType),
StructField("物流公司(货代)", StringType),
StructField("集装箱箱号", StringType),
StructField("货物名称", StringType),
StructField("货重(吨)", IntegerType)
))
//创建DataFrame
val df:DataFrame = spark
.read
.option("sep", ",") // 以“,”为分隔符分割
.option("quote", "'") // 设置字段引号为单引号
.option("escape", "'") // 设置转义字符为反斜杠
.option("header","true") //是否将第一行作为表头
.option("charset", "gbk") // 指定字符编码格式为 GBK
.schema(schema) // 修改后的字段替换
.format("csv") //文件为csv格式
.load("input/hdfs/物流信息2022.csv") //后期换为hdfs地址
// 提取出users2022表中的所有客户名称
val rows = filteredDf.select("客户名称").collect()
val result = ListBuffer.empty[String].toArray
for (row <- rows) {
val value = row.getAs[String]("客户名称")
result :+ value
}
//过滤物流信息2022.csv文件中的客户名称不在users.csv文件的客户名称中的数据
val df4 = df.filter(!col("客户名称").isin(result:_*))
// TODO 把df4治理完成的数据存放起来
//df4.coalesce(1).write.csv("output/finish2")
//数据治理 3.治理完成数据和异常数据分开存放,异常数据提供处理界面,并能重新治理。
//异常数据1 客户编号位数不为18位的
val wrongData1 = dfNull.filter(length(col("客户编号"))=!=18)
//异常数据2 其中有一行一个数据项为空
val filterRdd = df2.rdd.filter(row => row.anyNull)
val wrongData2 = spark.createDataFrame(filterRdd, df2.schema)
//异常数据3 客户编号中的出生年份在2023年之后的
val wrongData3 = wrongData1.filter(idCardYear.cast("int") > 2023)
//异常数据4 物流信息2022.csv文件中的客户名称不在users.csv文件的客户名称中的数据
val wrongData4 = df.filter(col("客户名称").isin(result:_*))
//TODO 异常数据 数据为空、身份证错误、物流信息客户不在客户数据中
//wrongData2.coalesce(1).write.csv("output/wrong/Null")
//wrongData3.coalesce(1).write.csv("output/wrong/WrongIdCard")
//wrongData4.coalesce(1).write.csv("output/wrong/notInUsers2022")
//关闭spark连接
spark.stop()
}
}
二、达梦启云云原生大数据平台部署spark测试
1.使用大数据平台上的spark运行Scala代码
遇到报错
Exception in thread "main" java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps;
at test$.main(test.scala:90)
at test.main(test.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:951)
at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:203)
at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:90)
at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:1039)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:1048)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
搜索后发现是spark版本与Scala的与大数据平台上的不一致,解决 ing~~