mysql - Spark 1.4.1 : Issue when reading MySQL BigInt columns

标签 mysql apache-spark

读取 BigInt 类型的 MySQL 列(例如下面的 BIGINT(21) UNSIGNED)时,Spark 无法强制转换 java.math.BigDecimal 到以下代码段中的 String:

val driver = "com.mysql.jdbc.Driver"
val server = ...
val infoSchema = "INFORMATION_SCHEMA"
val port = 3306
val user = ...
val pw = ...
val dbUrl = s"jdbc:mysql://$server:$port/$infoSchema"

val dbProperties = new java.util.Properties()
dbProperties.setProperty("driver", driver)
dbProperties.setProperty("user", user)
dbProperties.setProperty("password", pw)

val schema = ...
val table = ...

val cols = sqlContext.read.jdbc(dbUrl, "COLUMNS", dbProperties)
  .filter(col("TABLE_SCHEMA") === schema && col("TABLE_NAME") === table)
  .map(_.getValuesMap[String](Seq("ORDINAL_POSITION", "COLUMN_NAME")))
  .collect()
  .toList

cols.map(e => e("COLUMN_NAME"))
cols.map(e => e("ORDINAL_POSITION")) // java.math.BigDecimal cannot be cast to java.lang.String

但是,当我执行以下操作时,没有问题:

val num = new java.math.BigDecimal(1)
num.toString

这是一个错误还是我遗漏了什么?

最佳答案

Row.getValuesMap[T] 不用于类型转换。相反,它明确声明值的类型为 T(内部它只是一个 get 后跟 asInstanceOf[T])和 BigDecimal 显然不是 String

你可以:

  • 添加隐式转换。
  • 使用_.getValuesMap[Any]
  • 在映射之前使用 SQL 转换。

    withColumn("ORDINAL_POSITION", $"ORDINAL_POSITION".cast(StringType))
    

但说实话,所有这些选项都相当丑陋,直接提取值更有意义:

sqlContext.read.jdbc(...).filter(...)
  .select("ORDINAL_POSITION", "COLUMN_NAME")
  .rdd
  .map { case Row(i: java.math.BigDecimal, c: String) => (i, c) }

关于mysql - Spark 1.4.1 : Issue when reading MySQL BigInt columns,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39080789/

相关文章:

java - 如何使用 JUNit 测试 Java-Spark?

java - 在没有 "run-example"脚本的情况下运行 Spark Kafka wordcount.java 示例

azure - 在Azure databricks中,将pyspark数据帧写入eventhub花费的时间太长,因为数据帧中有300万条记录

php - 将数组传递到 PDO

MySQL-选择具有覆盖集合的值的组

mysql - 为什么在同一网络中使用动态 dns 进行端口转发时连接失败

php - prestashop -如何查明产品是否可供销售

scala - 使用 spark 将 null 设置为 Hive 表中数字数据类型的值

apache-spark - 如何附加到 HDFS 中的同一文件(spark 2.11)

javascript - PHP 脚本不返回查询,但 MySql 查询有效