用于 Kudu 兼容性的 Spark 数据帧转换列

Posted

技术标签:

【中文标题】用于 Kudu 兼容性的 Spark 数据帧转换列【英文标题】:Spark dataframe cast column for Kudu compatibility 【发布时间】:2019-05-15 19:27:06 【问题描述】:

(我是 Spark、Impala 和 Kudu 的新手。)我正在尝试通过 Kudu 在 Spark 中将表从 Oracle DB 复制到具有相同结构的 Impala 表。当代码尝试将 Oracle NUMBER 映射到 Kudu 数据类型时出现错误。如何更改 Spark DataFrame 的数据类型以使其与 Kudu 兼容?

这是从 Oracle 到 Impala 的一对一数据副本。我已经提取了源表的 Oracle 模式,并创建了一个具有相同结构(相同的列名和合理的数据类型映射)的目标 Impala 表。我希望 Spark+Kudu 能够自动映射所有内容并复制数据。相反,Kudu 抱怨它无法映射 DecimalType(38,0)

我想指定“第 1 列,名称为 SOME_COL,在 Oracle 中为 NUMBER,应映射到在 Kudu 中支持的 LongType”。

我该怎么做?

// This works
val df: DataFrame = spark.read
  .option("fetchsize", 10000)
  .option("driver", "oracle.jdbc.driver.OracleDriver")
  .jdbc("jdbc:oracle:thin:@(DESCRIPTION=...)", "SCHEMA.TABLE_NAME", partitions, props)

// This does not work  
kuduContext.insertRows(df.toDF(colNamesLower: _*), "impala::schema.table_name")
// Error: No support for Spark SQL type DecimalType(38,0)
// See https://github.com/cloudera/kudu/blob/master/java/kudu-spark/src/main/scala/org/apache/kudu/spark/kudu/SparkUtil.scala

// So let's see the Spark data types
df.dtypes.foreachcase (colName, colType) => println(s"$colName: $colType")
// Spark  data type: SOME_COL DecimalType(38,0)
// Oracle data type: SOME_COL NUMBER -- no precision specifier; values are int/long
// Kudu   data type: SOME_COL BIGINT

【问题讨论】:

【参考方案1】:

显然,当从 JDBC 数据源读取时,我们可以specify a custom schema。

connectionProperties.put("customSchema", "id DECIMAL(38, 0), name STRING")
val jdbcDF3 = spark.read
  .jdbc("jdbc:postgresql:dbserver", "schema.tablename", connectionProperties)

那行得通。我可以像这样指定customSchema

col1 Long, col2 Timestamp, col3 Double, col4 String

这样,代码就可以工作了:

import spark.implicits._
val df: Dataset[case_class_for_table] = spark.read
  .option("fetchsize", 10000)
  .option("driver", "oracle.jdbc.driver.OracleDriver")
  .jdbc("jdbc:oracle:thin:@(DESCRIPTION=...)", "SCHEMA.TABLE_NAME", partitions, props)
  .as[case_class_for_table]
kuduContext.insertRows(df.toDF(colNamesLower: _*), "impala::schema.table_name")

【讨论】:

以上是关于用于 Kudu 兼容性的 Spark 数据帧转换列的主要内容,如果未能解决你的问题,请参考以下文章

通过将键作为列将 json 字典转换为 spark 数据帧

Spark Kudu 结合

Spark:如何从 Spark 数据帧行解析和转换 json 字符串

如何将spark数据帧列名和行数据转换为json数据

hadoop+spark+kudu

从缓存中删除 spark 数据帧