JDBC的ResultSet游标转spark的DataFrame,数据类型的映射以TeraData数据库为例
1.编写给ResultSet添加spark的schema成员及DF(DataFrame)成员
/*
spark、sc对象因为是全局的,没有导入,需自行定义
teradata的字段类型转换成spark的数据类型
*/ import java.sql.{ResultSet, ResultSetMetaData} import org.apache.spark.sql.types._
import org.apache.spark.sql.{DataFrame, Row} object addDataframeMember { trait ResultSetMetaDataToSchema {
def columnCount: Int def schema: StructType
} implicit def wrapResultSetMetaData(rsmd: ResultSetMetaData) = {
new ResultSetMetaDataToSchema {
def columnCount = rsmd.getColumnCount def schema = {
def tdCovert(tdDpeStr: String, precision: Int = 0, scale: Int = 0, className: String = ""): DataType = {
tdDpeStr match {
case "BYTEINT" => IntegerType
case "SMALLINT" => Integerype
case "INTEGER" => IntegerType
case "BIGINT" => LongType
case "FLOAT" => DoubleType
case "CHAR" => StringType
case "DECIMAL" => DecimalType(precision, scale)
case "VARCHAR" => StringType
case "BYTE" => ByteType
case "VARBYTE" => ByteType
case "DATE" => DateType
case "TIME" => TimestampType
case "TIMESTAMP" => TimestampType
case "CLOB" => StringType
case "BLOB" => BinaryType
case "Structured UDT" => ObjectType(Class.forName(className))
}
} def col2StructField(rsmd: ResultSetMetaData, i: Int): StructField = StructField(rsmd.getColumnName(i), tdCovert(rsmd.getColumnTypeName(i), rsmd.getPrecision(i), rsmd.getScale(i), rsmd.getColumnClassName(i)), rsmd.isNullable(i) match { case 1 => true case 0 => false }).withComment(rsmd.getColumnLabel(i)) def rsmd2Schema(rsmd: ResultSetMetaData): StructType = (1 to columnCount).map(col2StructField(rsmd, _)).foldLeft(new StructType)((s: StructType, i: StructField) => s.add(i)) rsmd2Schema(rsmd)
}
}
} trait ResultSetToDF {
def schema: StructType def DF: DataFrame
} implicit def wrapResultSet(rs: ResultSet) = {
def rsmd = rs.getMetaData def toList[T](retrieve: ResultSet => T): List[T] = Iterator.continually((rs.next(), rs)).takeWhile(_._1).map(r => r._2).map(retrieve).toList def rsContent2Row(rs: ResultSet): Row = Row.fromSeq(Array.tabulate[Object](rsmd.columnCount)(i => rs.getObject(i + 1)).toSeq) new ResultSetToDF {
def schema = rsmd.schema def DF = spark.createDataFrame(sc.parallelize(toList(rsContent2Row)), schema)
} } }
2.正常基于JDBC连接并且获得数据集游标
import java.sql.{Connection, DriverManager}
/*
获取TeraData的连接
*/
val (dialect, host, user, passwd, database, charset) = ("teradata", "ip", "user", "password", "database", "ASCII")
val tdConf = collection.immutable.Map(
"driver" -> "com.ncr.teradata.TeraDriver",
"uri" -> s"jdbc:$dialect://$host/CLIENT_CHARSET=EUC_CN,TMODE=TERA,COLUMN_NAME=ON,CHARSET=ASCII,database=$database",
"username" -> user,
"password" -> passwd
)
def getTeraConn: Connection = {
Class.forName(tdConf("driver"))
DriverManager.getConnection(tdConf("uri"), tdConf("username"), tdConf("password"))
}
val sql = "SELECT TOP 10 * FROM xxx"
var conn = getTeraConn
val stmt = conn.createStatement()
val rs = stmt.executeQuery(sql)
3.导入隐式转换,调用成员
import addDataframeMember.wrapResultSet
rs.DF.show()
JDBC的ResultSet游标转spark的DataFrame,数据类型的映射以TeraData数据库为例的更多相关文章
- Spark操作dataFrame进行写入mysql,自定义sql的方式
业务场景: 现在项目中需要通过对spark对原始数据进行计算,然后将计算结果写入到mysql中,但是在写入的时候有个限制: 1.mysql中的目标表事先已经存在,并且当中存在主键,自增长的键id 2. ...
- Spark:将DataFrame写入Mysql
Spark将DataFrame进行一些列处理后,需要将之写入mysql,下面是实现过程 1.mysql的信息 mysql的信息我保存在了外部的配置文件,这样方便后续的配置添加. //配置文件示例: [ ...
- Spark:DataFrame批量导入Hbase的两种方式(HFile、Hive)
Spark处理后的结果数据resultDataFrame可以有多种存储介质,比较常见是存储为文件.关系型数据库,非关系行数据库. 各种方式有各自的特点,对于海量数据而言,如果想要达到实时查询的目的,使 ...
- spark第七篇:Spark SQL, DataFrame and Dataset Guide
预览 Spark SQL是用来处理结构化数据的Spark模块.有几种与Spark SQL进行交互的方式,包括SQL和Dataset API. 本指南中的所有例子都可以在spark-shell,pysp ...
- Oracle使用jdbc调用带游标参数的存储过程
package com.jckb.procedure; import java.sql.CallableStatement; import java.sql.Connection; import ja ...
- MySQL数据库学习笔记(九)----JDBC的ResultSet接口(查询操作)、PreparedStatement接口重构增删改查(含SQL注入的解释)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- pandas和spark的dataframe互转
pandas的dataframe转spark的dataframe from pyspark.sql import SparkSession # 初始化spark会话 spark = SparkSess ...
- 【spark】dataframe常见操作
spark dataframe派生于RDD类,但是提供了非常强大的数据操作功能.当然主要对类SQL的支持. 在实际工作中会遇到这样的情况,主要是会进行两个数据集的筛选.合并,重新入库. 首先加载数据集 ...
- [Spark][Python][DataFrame][RDD]DataFrame中抽取RDD例子
[Spark][Python][DataFrame][RDD]DataFrame中抽取RDD例子 sqlContext = HiveContext(sc) peopleDF = sqlContext. ...
随机推荐
- mysql 5.5和5.6版本关于timestamp not null类型字段关于null的处理
Server version: 5.5.33-31.1-log Percona Server (GPL), Release rel31.1, Revision 566 mysql> CREATE ...
- Flutter-charts_flutter圖表
pub.dev搜索charts_flutter 導入依賴 charts_flutter: ^0.8.1 項目導入 import 'package:charts_flutter/flutter.dart ...
- 容器(collection)初步
容器(集合)的分类: 泛型(generic):本质是数据类型的参数化(提前告诉编译器,在调用泛型时必须传入实际类型) 例:E即为在主函数中定义的传入的实际类型 class MyCollection&l ...
- hdu 5963:朋友
刚看到这题时感觉是树上博弈,然后我开始用一维的数据找规律.发现在一维的树上,如果把各边的值合在一起当成一个二进制数,那么,ans只与奇偶性有关,于是,我提出了一个比较大胆的假设:若连接在root上的所 ...
- Angular:OnPush变化检测策略介绍
在OnPush策略下,Angular不会运行变化检测(Change Detection ),除非组件的input接收到了新值.接收到新值的意思是,input的值或者引用发生了变化.这样听起来不好理解, ...
- POJ 2502 Subway ( 最短路 && 最短路建图 )
题意 : 给出二维平面上的两个点代表起点以及终点,接下来给出若干条地铁线路,除了在地铁线路上行进的速度为 40km/h 其余的点到点间都只能用过步行且其速度为 10km/h ,现问你从起点到终点的最短 ...
- vue组件传值之父传子
1.父组件给子组件传值 home父组件 header子组件 关键字props home代码 <template> <div> <v-header :title=&q ...
- ResultSet用法集锦 (转)
转:http://soft-development.iteye.com/blog/1420323 结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是 ...
- idea2019.2 svn 忽略文件问题
自己用的是idea2019.2最新版本,今天提交的时候Commit Changes Dialog local changes refresh一直再刷新 其他的方法都是老版本都不适合 解决办法 找到Se ...
- 虚拟机中安装Linux_Centos7操作系统(最小化安装)
我们打开之前安装的VM, 点击 “创建新的虚拟机”: 我们选 典型 安装 简单点 然后下一步: 我们稍后安装操作系统 ,点下一步: 这里选 Linux 然后下拉 选CentOS 64位,然后下一步: ...