转载自: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. java 懒汉式、饿汉式单例模式 不含多线程的情况

    //饿汉式 提前生成了单例对象 class Singleton{ private static final Singleton instance=new Singleton(); private Si ...

  2. tensorflow 与cuda、cudnn的对应版本关系

    来源:https://www.cnblogs.com/zzb-Dream-90Time/p/9688330.html

  3. 《BUG创造队》作业8:软件测试与Alpha冲刺(第五天)

    项目 内容 这个作业属于哪个课程 2016级软件工程 这个作业的要求在哪里 实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 BUG创造队 作业学习目标 (1)掌握软件测试基础技术.(2)学习 ...

  4. 基于h5+的微信登录,hbuilder打包

    1.打开app项目的manifest.json的文件,选择模块权限配置,将OAuth(登录鉴权)模块添加至已选模块中 2.选择SDK配置,在plus.oauuth·登录鉴权中,勾选□ 微信登录,配置好 ...

  5. test20190731 夏令营NOIP训练16

    0+90+0=90.我只挑了T2做. 连接格点 有一个M行N列的点阵,相邻两点可以相连.一条纵向的连线花费一个单位,一条横向的连线花费两个单位.某些点之间已经有连线了,试问至少还需要花费多少个单位才能 ...

  6. CH6303 天天爱跑步

    6303 天天爱跑步 0x60「图论」例题 描述 小C同学认为跑步非常有趣,于是决定制作一款叫作<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成 ...

  7. 【shell】2、判断表达式、if语句

    文件类型判断 test -e filename:该文件名是否存在 test -f filename:该文件名是否存在且为文件(file) test -d filename:该文件名是否存在且为目录(d ...

  8. 2019/7/18 --1.<%@ include file=""%>与<jsp:include page=""/>两种方式的作用

    一.前言 身为一名coder有太多太多的知识点要去学,太多太多的东西要去记.往往一些小细节也就难免疏忽,但悲催的是多数困恼你的bug就是因为这些微不足道的知识点.我们又不是机器人,怎么可能什么都记得了 ...

  9. php技能树---大神的进阶之路

    PHP7 迎来巨大的性能提升,又一次回到关注的焦点.根据这些年在开发圈子总结的LNMP程序猿发展轨迹,结合个人经验体会,总结出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段 ...

  10. apt-get 和dpkg命令

    软件包下载:apt-get 1.apt-get install vim  下载vim 2.apt-get upgrade vim 升级vim 3.apt-get update 列出更新 debian软 ...