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. ...
随机推荐
- python 脚本编译成可执行二进制(exe)
本文python3,pyinstaller也支持py2 cmd下载模块pyinstaller 首先: pip install pyinstaller 其次: cmd下进入需要编译的xxx.py文件目录 ...
- python TypeError: must be str, not bytes错误
TypeError: must be str, not bytes错误: 解答: 写文件处 f=open(filename, 'w')应该写为 open(filename, 'wb') 读文件时 f= ...
- go mac 交叉编译 linux
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-w' -o server ./server.go
- 20180715-Java String类
public class StringDemo{ public static void main(String args[]){ char[] helloArray = {'h','e','l','l ...
- 学习日记14、EF 时间段查询
m_Rep.GetList(a => System.Data.Entity.DbFunctions.DiffDays(DateTime.Now, a.EndDate) < date); 命 ...
- 笨办法学Python(learn python the hard way)--练习程序39-40
下面是练习39-练习40,基于python3 #ex39.py 1 ten_things = "Apples Oranges Crows Telephone Light Sugar" ...
- (转)运行pip报错:Fatal error in launcher: Unable to create process using '"'
转:https://blog.csdn.net/cjeric/article/details/73518782 在新环境上安装python的时候又再次遇到了这个情况,这次留意了一下,发现原来的文章有错 ...
- noi.ac#228 book
分析 代码 #include<bits/stdc++.h> using namespace std; #define int long long const int inf =1e18; ...
- STM32 I2C 难点---这个不错,留着慢慢研究
来自:http://bbs.ednchina.com/BLOG_ARTICLE_2154168.HTM I2C 总线在所有嵌入式系统中用得极广, 是一个工业级别的总线, 但由于STM32 是一个32位 ...
- Android O编译前修改文件和目录权限
当需要修改某文件或路径权限时,我们可以在init.rc开机启动某节点添加chmod命令进行修改.但是对于system分区,由于是ro权限,在init.rc使用chmod修改权限无效.需要在文件编译时, ...