Spark通过修改DataFrame的schema给表字段添加注释(转载)
转载自:https://www.jianshu.com/p/e4c90dc08935
1、需求背景
通过Spark将关系型数据库(以Oracle为例)的表同步的Hive表,要求用Spark建表,有字段注释的也要加上注释。Spark建表,有两种方法:
- 用Spark Sql,在程序里组建表语句,然后用Spark.sql("建表语句")建表,这种方法麻烦的地方在于你要读取Oracle表的详细的表结构信息,且要进行Oracle和Hive的字段类型进行一一对应
- 用DataFrame 的saveAsTable方法,这种方法如果对应的数据库里没有表,则Spark会根据DataFrame的schema自动建表,比较简单,不用考虑字段类型匹配转化问题,但是这种方法有一个问题,Spark读取Oracle的表为DataFrame时,并不能将表字段的注释读进来,所以就有了如标题所示的需求。(一开始以为DataFrame不能加注释,经过研究,发现是可以的!)
2、如何查看DataFrame是否有注释
前面讲到DataFrame里没有Oracle的注释信息,但是如果数据源为Hive的话,是可以将注释获取到的。
2.1 新建Hive测试表(带注释)
create table `test` (
`id` string comment 'ID',
`Name` string comment '名字'
)
comment '测试';

2.2 Spark读取hive表并打印注释(在spark-shell里执行)
首先看一下df.printSchema里并没有注释信息
sql("use test")
val df = spark.table("test")
df.printSchema
root
|-- id: string (nullable = true)
|-- name: string (nullable = true)

用下面这行代码便可以打印注释信息:
df.schema.foreach(s=>println(s.name,s.metadata))
(id,{"comment":"ID","HIVE_TYPE_STRING":"string"})
(name,{"comment":"名字","HIVE_TYPE_STRING":"string"})

3、读取Oracle表并打印DataFrmae的元数据信息
3.1 新建Oracle测试表(带注释)
CREATE TABLE ORA_TEST (
ID VARCHAR2(),
NAME VARCHAR2()
);
COMMENT ON COLUMN ORA_TEST.ID IS 'ID';
COMMENT ON COLUMN ORA_TEST.NAME IS '名字';
COMMENT ON TABLE ORA_TEST IS '测试';
- 注:上面的注释语句和建表语句需要分开执行,或者也可以在数据库工具执行脚本,比如我用的DBeaver用快捷键Alt+x即可。当然也可以在工具的界面直接建表均可。

3.2 读取Oracle表,并打印元数据
代码:
package com.dkl.leanring.spark.sql.Oracle
import org.apache.spark.sql.SparkSession
object OracleSchemaDemo {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("OracleSchemaDemo").master("local").getOrCreate()
val df = spark.read
.format("jdbc")
.option("url", "jdbc:oracle:thin:@192.168.44.128:1521:orcl")
.option("dbtable", "ORA_TEST")
.option("user", "bigdata")
.option("password", "bigdata")
.option("driver", "oracle.jdbc.driver.OracleDriver")
.load()
df.schema.foreach(s => println(s.name, s.metadata))
spark.stop
}
}
(ID,{"name":"ID","scale":})
(NAME,{"name":"NAME","scale":})

注:Spark2.3.0和Spark2.2.1的元数据不太一样,上面的结果是Spark2.2.1(也是我写博客测试用的),项目中用的Spark2.3.0,2.3.0的元数据是空的,如下
(ID,{})
(NAME,{})
可见并没有注释信息
3.3 给DataFrame添加注释
import org.apache.spark.sql.types._
val commentMap = Map("ID" -> "ID", "NAME" -> "名字") val schema = df.schema.map(s => {
s.withComment(commentMap(s.name))
}) //根据添加了注释的schema,新建DataFrame
val new_df = spark.createDataFrame(df.rdd, StructType(schema)).repartition() new_df.schema.foreach(s => println(s.name, s.metadata))
(ID,{"comment":"ID","name":"ID","scale":})
(NAME,{"comment":"名字","name":"NAME","scale":})

4、 测试写到Hive表有没有注释
需将前面代码中的spark改为支持hive,即加上enableHiveSupport()
spark.sql("use test")
new_df.write.mode("overwrite").saveAsTable("ORA_TEST")
然后在hive里看一下,是否有注释

可以看到,成功的把注释也保存到里hive里
5、附录
附上在Eclipse运行的完整代码
package com.dkl.leanring.spark.sql.Oracle import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types._ object OracleSchemaDemo {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("OracleSchemaDemo").master("local").enableHiveSupport().getOrCreate()
val df = spark.read
.format("jdbc")
.option("url", "jdbc:oracle:thin:@192.168.44.128:1521:orcl")
.option("dbtable", "ORA_TEST")
.option("user", "bigdata")
.option("password", "bigdata")
.option("driver", "oracle.jdbc.driver.OracleDriver")
.load()
df.schema.foreach(s => println(s.name, s.metadata)) val commentMap = Map("ID" -> "ID", "NAME" -> "名字") val schema = df.schema.map(s => {
s.withComment(commentMap(s.name))
}) //根据添加了注释的schema,新建DataFrame
val new_df = spark.createDataFrame(df.rdd, StructType(schema)).repartition() new_df.schema.foreach(s => println(s.name, s.metadata)) spark.sql("use test")
//保存到hive
new_df.write.mode("overwrite").saveAsTable("ORA_TEST") spark.stop }
}
Spark通过修改DataFrame的schema给表字段添加注释(转载)的更多相关文章
- mysql 数据库 表字段添加表情兼容
项目中的几个需要支持Emoji表情符号,手机自带的表情,其实添加也很简单: 1 修改数据库 配置my.cnf init-connect='SET NAMES utf8mb4' ...
- oracle 表字段添加 修改 删除语法
修改列名 alter table 表明 rename column rename 老列名 to 新列名添加 字段alter table 表名 add(字段名 类型):删除字段alter table 表 ...
- PowerDesigner15.1给自定义架构表字段添加MS_Description出错
原因:系统函数sp_addextendedproperty 的第3个参数(用户名) 应该是Schema.但PD在生成的时候却是’user’ 解决方法 在PDM时.DataBase >> E ...
- Maven插件mybatis-generator,如何让生成的PO类的field上有对应表字段的注释
前言 去年刚入职的时候,我就发现,po类(和数据库表对应的类)上,一片都是光秃秃的,什么注释都没有,类上没注释,field上也没注释. 在以前的项目中,其实我们都是有生成注释的,比如,对于下面这个表: ...
- @MySQL为表字段添加索引
删除索引~ DROP INDEX `idx_dict_type` ON `article` 1.添加PRIMARY KEY(主键索引): ALTER TABLE `table_name` ADD PR ...
- Mysql如何为表字段添加索引???
1.添加PRIMARY KEY(主键索引): ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2.添加UNIQUE(唯一索引) : ALTE ...
- Mysql优化-为表字段添加索引
1.添加PRIMARY KEY(主键索引): ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2.添加UNIQUE(唯一索引) : ALTE ...
- ORACLE修改表字段顺序
1.若'GYZL_BZPWL_TB' 为要修改的表名,注意表名一定要大写!此句可以获取表的id.select object_id from all_objects where object_name= ...
- oracle查看表名称和表字段注释
--查询该表字段的注释select * from user_col_comments where Table_Name like '%SMS%' --查询类似表select * from user_t ...
随机推荐
- python算法与数据结构-希尔排序算法(35)
一.希尔排序的介绍 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每 ...
- Django之路——7 django与ajax
Ajax简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输的数 ...
- vbs查找Excel中的Sheet2工作表是否存在不存在新建
set oExcel = CreateObject( "Excel.Application" ) oExcel.Visible = false '4) 打开已存在的工作簿: oEx ...
- 「CQOI2015」选数
「CQOI2015」选数 题目描述 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都 ...
- 行为型模式(七) 策略模式(Stragety)
一.动机(Motivate) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持不使用的算法也是一个性能负担.如何在运行时 ...
- 通过 ffmpeg 获取视频第一帧(指定时间)图片
最近做一个上传教学视频的方法,上传视频的同时需要上传视频缩略图,为了避免用户上传的缩略图与视频内容不符,经理要求直接从上传的视频中截图视频的某一帧作为缩略图,并给我推荐了FFMPEG.FFMPEG 功 ...
- Java - 框架之 Spring
一. IOC 和 DI IOC : 控制反转,将对象的创建权反转给了 Spring.DI : 依赖注入,前提是必须要有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入(设置)进来 ...
- Linux学习建议[转]
端正学习态度学linux不会为了当黑客或者骇客,如果你为了当黑客或骇客而学习Linux,那么你离进监狱不远了,只是时间早晚而已.很多小白都知道“黑客攻击工具”很多来源与Linux平台上的,我也曾指导过 ...
- Problem 4 dp
$des$ 小 $Y$ 十分喜爱光学相关的问题, 一天他正在研究折射.他在平面上放置了 $n$ 个折射装置, 希望利用这些装置画出美丽的折线.折线将从某个装置出发, 并且在经过一处装置时可以转向, 若 ...
- MySQL 获得 当前日期时间 函数
mysql> select now(); 输出 -- :: 例子 mysql> ), now(); +---------------------+----------+---------- ...