Spark使用ur命令读取jdbc db2

问题描述

我正在尝试使用read.jdbc从Db2提取数据以进行触发。我无法在查询中传递UR字符串。

如何在spark jdbc读取中将隔离设置为UR。

import json
#spark = SparkSession.builder.config('spark.driver.extraClasspath','/home/user/db2jcc4.jar').getorCreate()
jdbcUrl = "jdbc:db2://{0}:{1}/{2}".format("db2.1234.abcd.com","3910","DSN")
connectionProperties = {
  "user" : "user1","password" : "password1","driver" : "com.ibm.db2.jcc.DB2Driver","fetchsize" : "100000"
}
pushdown_query = "(SELECT T6.COLUMN1,T6.COLUMN2,TO_DATE('07/11/2019 10:52:24','MM/DD/YYYY HH24:MI:SS') AS INSERT_DATE FROM DB1.T6 WITH UR ) ALIAS"
print(jdbcUrl)
df = spark.read.jdbc(url=jdbcUrl,table=pushdown_query,column="COLUMN1",lowerBound=1,upperBound=12732076,numPartitions=5,properties=connectionProperties)

此操作失败并显示错误:com.ibm.db2.jcc.am.sqlSyntaxErrorException:DB2 sql错误sqlCODE = -199,sqlSTATE = 42601,sqlERRMC = UR ;; FETCH,)偏移量限制相交顺序组在其中加入,驱动程序= 4.13.80

如果我删除UR,则它正常工作。有没有办法通过Spark jdbc read中的UR传递查询

jdbc中有连接参数,但这仅适用于写入 isolatedLevel事务隔离级别,适用于当前连接。它可以是NONE,READ_COMMITTED,READ_UNCOMMITTED,REPEATABLE_READ或SERIALIZABLE之一,与JDBC的Connection对象定义的标准事务隔离级别相对应,认值为READ_UNCOMMITTED。此选项仅适用于写作。请参考java.sql.Connection中的文档。

下面将解决问题吗?

connectionProperties = {
      "user" : "user1","fetchsize" : "100000","isolationLevel" : "READ_UNCOMMITTED" 
    }

解决方法

根据 DB2 文档,在连接细节中连接到 db2 时,我们可以通过 defaultIsolationLevel=1 这意味着未提交的读取。 查看链接:https://www.ibm.com/support/pages/how-set-isolation-level-db2-jdbc-database-connections

,

根据文档和此Blog的规定,在读取操作中会忽略绝缘等级。

说实话,我不明白为什么,因为java.sql.connection setIsolationLevel为整个连接设置了默认值,而afaik读取本身并没有设置隔离级别。

尽管如此,为here提供了另一种方法。

因此,应该为您解决以下问题:

#spark = SparkSession.builder.config('spark.driver.extraClassPath','/home/user/db2jcc4.jar').getOrCreate()
jdbcUrl = "jdbc:db2://{0}:{1}/{2}".format("db2.1234.abcd.com","3910","DSN")
connectionProperties = {
  "user" : "user1","password" : "password1","driver" : "com.ibm.db2.jcc.DB2Driver","fetchsize" : "100000"
}

df = spark.read.jdbc(url=jdbcUrl,table="DB1.T6",predicates=["1=1 WITH UR"],properties=connectionProperties).select("COLUMN1","COLUMN2",...)

我使用1 = 1子句来创建有效的where条件。 这个方法看起来确实像必须有一种更清洁的方法,但是效果很好