PySpark:当通过 JDBC 在 Oracle 中创建表时,为啥我会得到“没有为类 oracle.jdbc.driver.T4CRowidAccessor 实现 getLong”?

Posted

技术标签:

【中文标题】PySpark:当通过 JDBC 在 Oracle 中创建表时,为啥我会得到“没有为类 oracle.jdbc.driver.T4CRowidAccessor 实现 getLong”?【英文标题】:PySpark: Why do I get 'getLong not implemented for class oracle.jdbc.driver.T4CRowidAccessor' when creating a table in Oracle via JDBC?PySpark:当通过 JDBC 在 Oracle 中创建表时,为什么我会得到“没有为类 oracle.jdbc.driver.T4CRowidAccessor 实现 getLong”? 【发布时间】:2021-02-02 19:27:16 【问题描述】:

我是 Pyspark 的新手,我已经很久没有看到任何 Java 了,所以要温柔。我在 SO 上看到了类似的问题,但它们似乎都是纯 Java 而不是 Pyspark。我正在尝试通过 JDBC 将 Spark DataFrame 写入 Oracle 表。我能够成功连接和查询数据库,但是当我去创建一个这样的新表时:

df.write.jdbc('jdbc:oracle:thin:@host:port/service', create_table,
              mode='overwrite',
              properties='user': 'user', 'password': 'password'])

我收到错误消息java.sql.SQLException: Invalid column type: getLong not implemented for class oracle.jdbc.driver.T4CRowidAccessor

我怀疑这与df.dtypesbigint 的列 ROW_ID 有关。 ROW_ID 类似于下表,似乎与推断的数据类型不一致。

ROW_ID
AABBVMAGRAAAJfsAAA
AABBVMAGRAAAJftAAA
AABBVMAGRAAAJfyAAB
AABBVMAGRAAAJfvAAB
AABBVMAGRAAAJfwAAB
AABBVMAGRAAAJf3AAI

编辑:

我尝试将数据类型从 bigint 转换为 string 使用:

from pyspark.sql.functions import col
from pyspark.sql.types import StringType
correct_dtypes = df.withColumn('ROW_ID', col('ROW_ID').cast(StringType()))
correct_dtypes.write.jdbc('jdbc:oracle:thin:@host:port/service', create_table,
                          mode='overwrite',
                          properties='user': 'user', 'password': 'password')

但我仍然遇到同样的错误。

【问题讨论】:

【参考方案1】:

一种可能的解决方案是在保存期间使用createTableColumnTypes 选项,并将麻烦的 bigint 列强制转换为 oracle dbs 端的 varchar2:

(correct_dtypes.write.
.option("createTableColumnTypes", "ROW_ID VARCHAR2(18)")
.jdbc('jdbc:oracle:thin:@host:port/service',
                          create_table, mode='overwrite',
                          properties='user': 'user',
                          'password': 'password'))

【讨论】:

以上是关于PySpark:当通过 JDBC 在 Oracle 中创建表时,为啥我会得到“没有为类 oracle.jdbc.driver.T4CRowidAccessor 实现 getLong”?的主要内容,如果未能解决你的问题,请参考以下文章

pyspark 读取格式 jdbc 生成 ORA-00903: invalid table name 错误

通过 JDBC 进行并行化 - Pyspark - 并行化如何使用 JDBC 工作?

PySpark 中 JDBC 上的自定义分区

Informix JDBC PySpark 将列名中的结果作为列值读取

连接到 sql server 时出现 pyspark jdbc 错误

Pyspark可以使用JDBC来传递Alter Table吗