【问题标题】:Spark JDBC to DashDB (DB2) with CLOB errors带有 CLOB 错误的 Spark JDBC 到 DashDB (DB2)
【发布时间】:2017-04-07 21:29:43
【问题描述】:

我正在努力将我的 spark 应用程序连接到 DashDB。目前,我可以很好地加载我的数据。

但是,我无法将 DataFrame 保存到 DashDB。

任何见解都会有所帮助。

  var jdbcSets = sqlContext.read.format("jdbc").options(Map("url" -> url, "driver" -> driver, "dbtable" -> "setsrankval")).load()
  jdbcSets.registerTempTable("setsOpponentRanked")
  jdbcSets = jdbcSets.coalesce(10)
  sqlContext.cacheTable("setsOpponentRanked")

但是,当我尝试保存大型 DataFrame 时,出现错误:

DB2 SQL 错误:SQLCODE=-1666、SQLSTATE=42613、SQLERRMC=CLOB、DRIVER=4.19.26

我用来保存数据的代码如下:

val writeproperties = new Properties()
  writeproperties.setProperty("user", "dashXXXX")
  writeproperties.setProperty("password", "XXXXXX")
  writeproperties.setProperty("rowId", "false")
  writeproperties.setProperty("driver", "com.ibm.db2.jcc.DB2Driver")
  results.write.mode(SaveMode.Overwrite).jdbc(writeurl, "players_stat_temp", writeproperties)

可以在此处查看示例测试数据集:

println("Test set: "+results.first()) 
Test set: ['Damir DZUMHUR','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test',null,null,null,null,null,null,null]

DataFrame 架构如下:

    root
 |-- PLAYER: string (nullable = true)
 |-- set01: string (nullable = true)
 |-- set02: string (nullable = true)
 |-- set12: string (nullable = true)
 |-- set01weakseed: string (nullable = true)
 |-- set01medseed: string (nullable = true)
 |-- set01strongseed: string (nullable = true)
 |-- set02weakseed: string (nullable = true)
 |-- set02medseed: string (nullable = true)
 |-- set02strongseed: string (nullable = true)
 |-- set12weakseed: string (nullable = true)
 |-- set12medseed: string (nullable = true)
 |-- set12strongseed: string (nullable = true)
 |-- set01weakrank: string (nullable = true)
 |-- set01medrank: string (nullable = true)
 |-- set01strongrank: string (nullable = true)
 |-- set02weakrank: string (nullable = true)
 |-- set02medrank: string (nullable = true)
 |-- set02strongrank: string (nullable = true)
 |-- set12weakrank: string (nullable = true)
 |-- set12medrank: string (nullable = true)
 |-- set12strongrank: string (nullable = true)
 |-- minibreak: string (nullable = true)
 |-- minibreakweakseed: string (nullable = true)
 |-- minibreakmedseed: string (nullable = true)
 |-- minibreakstrongseed: string (nullable = true)
 |-- minibreakweakrank: string (nullable = true)
 |-- minibreakmedrank: string (nullable = true)
 |-- minibreakstrongrank: string (nullable = true)

我查看了 jdbc DB2Dialect,发现 StringType 的代码被映射到 CLOB。我想知道以下是否会有所帮助:

private object DB2CustomDialect extends JdbcDialect {
    override def canHandle(url: String): Boolean = url.startsWith("jdbc:db2")
    override def getJDBCType(dt: DataType): Option[JdbcType] = dt match {
            case StringType => Option(JdbcType("VARCHAR(10000)", java.sql.Types.VARCHAR))
            case BooleanType => Option(JdbcType("CHAR(1)", java.sql.Types.CHAR))
            case _ => None
    }
}

【问题讨论】:

  • 覆盖关键字不起作用;此外,删除它后,我仍然面临同样的问题。我正在使用 Spark 3 和 DB2。

标签: scala jdbc apache-spark dashdb


【解决方案1】:

请注意,DSX(即 datascience.ibm.com)尚未立即解决此问题。因此,在 DSX 中使用带有 dashDB 的笔记本时,现在不再需要部署自定义方言了。

【讨论】:

    【解决方案2】:

    通过添加自定义方言效果很好。

    JdbcDialects.registerDialect(new DB2CustomDialect())
    

    【讨论】:

      【解决方案3】:

      是的,DB2Dialect 的当前实现确实不是最优的。我们会看一下,可能会创建一个拉取请求来将 StringType 映射更改为 VARCHAR。

      我猜想首先使用 CLOB 的想法是,当您希望能够存储所有长度的字符串时,这会更安全,而 VARCHAR 最多受 DB2/dashDB 页面大小的限制。但我认为不太可能将很长的字符串放入数据框的属性中,而 CLOB 会导致各种操作问题,例如DB2 中的 COLUMN ORGANIZED 表不支持它,这是 dashDB 中的默认表类型,这就是您在尝试将数据帧写入 dashDB 时遇到问题的原因。但是 CLOB 对 DB2 中的 IO 性能也有问题,因为它不一定像所有其他表数据一样缓存在数据库内存中。

      您现在可以做的解决方法确实只是按照您在上面提出的 JdbcDialects.registerDialect() 注册自己的自定义方言,直到上述拉取请求被接受。

      【讨论】:

      • 我遇到了完全相同的问题,但我使用的是 PySpark。我该如何解决这个问题?
      • 您也可以使用 Pixidust 的 Scala 桥接功能在 PySpark 笔记本中应用此修复。我写了一篇关于整个问题和解决方案的博客文章,并附有示例笔记本的链接:datascience.ibm.com/blog/…
      • 之前看过这篇文章,其实我用的是IBM的spark-submit,而不是Notebooks/DSX。你是说我需要在本地修复我的脚本,然后在 Spark 集群中提交它吗?由于 Spark 集群是托管服务,因此会安装所有这些依赖项吗?
      • 我尚未使用 spark-submit 验证修复。但我的假设是它也会在那里工作。 IE。通过 pixidust scala bridge 在 Python 脚本中集成 JDBC 方言注册。此外,尽管我们正在努力使用 dashDB 方言更新直接更新 Bluemix 中的 Spark,这样您就不必再在脚本和笔记本中进行这项工作了。该修复程序应该很快就会消失。所以请继续关注。
      • @TorstenSteinbach 有什么更新吗?我刚刚发现一堆使用 Spark 2.4 的 CLOB。补丁被拒绝了吗?你引用的博文不见了
      猜你喜欢
      • 2012-09-25
      • 1970-01-01
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      相关资源
      最近更新 更多