转载自: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给表字段添加注释(转载)的更多相关文章

  1. mysql 数据库 表字段添加表情兼容

    项目中的几个需要支持Emoji表情符号,手机自带的表情,其实添加也很简单: 1 修改数据库 配置my.cnf  init-connect='SET NAMES utf8mb4'             ...

  2. oracle 表字段添加 修改 删除语法

    修改列名 alter table 表明 rename column rename 老列名 to 新列名添加 字段alter table 表名 add(字段名 类型):删除字段alter table 表 ...

  3. PowerDesigner15.1给自定义架构表字段添加MS_Description出错

    原因:系统函数sp_addextendedproperty 的第3个参数(用户名) 应该是Schema.但PD在生成的时候却是’user’ 解决方法 在PDM时.DataBase >> E ...

  4. Maven插件mybatis-generator,如何让生成的PO类的field上有对应表字段的注释

    前言 去年刚入职的时候,我就发现,po类(和数据库表对应的类)上,一片都是光秃秃的,什么注释都没有,类上没注释,field上也没注释. 在以前的项目中,其实我们都是有生成注释的,比如,对于下面这个表: ...

  5. @MySQL为表字段添加索引

    删除索引~ DROP INDEX `idx_dict_type` ON `article` 1.添加PRIMARY KEY(主键索引): ALTER TABLE `table_name` ADD PR ...

  6. Mysql如何为表字段添加索引???

    1.添加PRIMARY KEY(主键索引): ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2.添加UNIQUE(唯一索引) : ALTE ...

  7. Mysql优化-为表字段添加索引

    1.添加PRIMARY KEY(主键索引): ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 2.添加UNIQUE(唯一索引) : ALTE ...

  8. ORACLE修改表字段顺序

    1.若'GYZL_BZPWL_TB' 为要修改的表名,注意表名一定要大写!此句可以获取表的id.select object_id from all_objects where object_name= ...

  9. oracle查看表名称和表字段注释

    --查询该表字段的注释select * from user_col_comments where Table_Name like '%SMS%' --查询类似表select * from user_t ...

随机推荐

  1. 题解 洛谷P4872 【OIer们的东方梦】

    一道码量比较大的广搜题,但让我这个辣鸡小学生自闭了一天呜呜呜. 一开始看数据\(n,m \leq 1000\)也并不是特别大,于是用就开始用广搜乱水了. 由于这道题每走一步的代价不是\(1\),所以并 ...

  2. python打造漏洞数据导出工具

    功能 [x] 支持导出的数据:IP地址.漏洞名称.风险等级.整改建议.漏洞描述.漏洞CVE编号.漏洞对应端口.漏洞对应协议.漏洞对应服务等. [x] 导出不同端口的同一个漏洞,也就是一个端口对应一个漏 ...

  3. Enterprise Architect 14破解版 安装包 安装教程

    安装包以及破解补丁下载: 链接:https://pan.baidu.com/s/1es0wN_6-d9pk4xnSN1SiFA 提取码:bor0 安装包链接失效可在下方留言 安装以及破解教程 参考链接 ...

  4. Linux iftop 安装与参数详解

    介绍 iftop是一款实时流量监控工具,监控TCP/IP连接等,缺点就是无报表功能.必须以root身份才能运行. .编译安装如果采用编译安装可以到iftop官网下载最新的源码包. 安装前需要已经安装好 ...

  5. python - django (request 获取 访问者的 IP)

    使用 Django 获取访问者的 IP if request.META.get('HTTP_X_FORWARDED_FOR'): ip = request.META.get("HTTP_X_ ...

  6. 【贪心】Communication System POJ 1018

    题目链接:http://poj.org/problem?id=1018 题目大意:有n种通讯设备,每种有mi个制造商,bi.pi分别是带宽和价格.在每种设备中选一个制造商让最小带宽B与总价格P的比值B ...

  7. linux 下安装 nginx 及所需的各种软件工具

    我当前的虚拟机是 vmware 15,用的镜像是centOs 7 CentOS-7-x86_64-DVD-1810.iso 确保你的虚拟机是通网的. 1.如果是新环境,没安装过gcc,那么先安装这个. ...

  8. Intel 80386 CPU

    一.80386 概述 80386处理器被广泛应用在1980年代中期到1990年代中期的IBM PC相容机中.这些PC机称为「80386电脑」或「386电脑」,有时也简称「80386」或「386」.80 ...

  9. Linux中三种SCSI target的介绍之LIO

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/scaleqiao/article/deta ...

  10. BZOJ 1406: [AHOI2007]密码箱

    二次联通门 : BZOJ 1406: [AHOI2007]密码箱 /* BZOJ 1406: [AHOI2007]密码箱 数论 要求 x^2 ≡ 1 (mod n) 可以转换为 x ^ 2 - k * ...