java.sql.SQLException:将 Spark 数据帧保存到 Sybase 时找不到类型“TIMESTAMP”

Posted

技术标签:

【中文标题】java.sql.SQLException:将 Spark 数据帧保存到 Sybase 时找不到类型“TIMESTAMP”【英文标题】:java.sql.SQLException: Can't find type 'TIMESTAMP' when saving Spark dataframe to Sybase 【发布时间】:2021-02-02 09:23:19 【问题描述】:

我在 java 应用程序中使用 spark,我必须将数据帧保存到现有的 db 表中。数据库是 Sybase。火花版本 3.0.1。我在数据框中有几个时间戳类型的字段。所以看起来它们不能映射到“日期时间”类型的数据库文件,但为什么不呢?我正在使用此语句尝试插入数据框:

outputDS.write().mode(SaveMode.Append).jdbc(URL, tableName, properties);

还有我如何在输出数据集中创建时间戳列的语句示例:

.withColumn("DateCreated", lit(new TimeStamp(System.currentTimeMillis())).cast(DataTypes.TimestampType))

这里是模式:

数据框架构:

rDay: timestamp
rName: string
rValue: double
rId: integer
rCountry: string
rRegion: string 
rCustomerId: string 
rLevel: string 
rUserCreated: string
rUserUpdated: string
rDateCreated: timestamp 
rDateUpdated: timestamp 

db 表架构:

rId                bigint
rCustomerId        bigint 
rCountry           varchar(50)
rRegion            varchar(15)
rName              varchar(50)
rValue             decimal(8,4)
rLevel             varchar(30)
rDay               datetime
rUserCreated       varchar(15)
rDateCreated       datetime 
rUserUpdated       varchar(15)
rDateUpdated       datetime 

因此,据我了解,要将行从 spark 数据帧插入到现有的 db 表中,它们的模式必须相同。但试图实现这一点我得到了这个例外:

java.sql.SQLException:找不到类型“TIMESTAMP”

当我尝试将字段的时间戳类型更改为例如 DateType 时,我得到另一个异常,例如“数据库中已经有一个对象 'tableName'”,所以我猜这是因为这次模式不匹配。那么,有没有办法以某种方式做到这一点?提前致谢!

【问题讨论】:

能否用数据框架构和表架构更新问题? 好的,我刚刚添加了。无法从源复制,所以它是近似模式,具有实际类型 由于您在目标数据库中有日期时间列,您应该将数据框中的列的数据类型更改为日期时间。您还应该确保列的顺序应该相同。很久以前我在 SQL 中遇到过类似的问题,我以这种方式解决了这个问题 但是spark DateTypes中没有DateTime这样的类型,只有Date,不合适,因为我也需要时间。当我读到 spark Timestamp 应该映射到数据库 datetime 以及 java.sql.Timestamp 映射到 db datetime 时。不过没想到订单,也许这是个线索,谢谢 在这种情况下,请确保将数据框中的时间戳列转换为目标数据库用于日期时间的格式,因为不同的格式也会导致错误。 【参考方案1】:

无需再次转换为 DataTypes.TimestampType 作为:

.withColumn("DateCreated", lit(new Timestamp(System.currentTimeMillis())))

已经给出DateCreated 类型的列timestamp

此外,您应该为此使用 Spark 内置函数 current_timestamp

.withColumn("DateCreated", current_timestamp())

我收到此异常 java.sql.SQLException: Can't find type 'TIMESTAMP'

我对 Sybase 不太了解,但是您可以尝试在写入表之前对时间戳列进行字符串化:

.withColumn("DateCreated", date_format(current_timestamp(), "yyyy-MM-dd HH:mm:ss"))

【讨论】:

所以,就这样试了,现在spark把这些字段保存为字符串。所以它与 db 'datetime' 类型不匹配,我得到 'java.sql.Exception: There's already a object named 'tableName' in the database' @sergio1399 您使用什么连接器从 spark 写入 Sybase? 其实我完全忘记了驱动程序。我已将此 .option("driver", driverClassName) 添加到写作语句中,它会有所帮助。非常感谢你!至少我解决了这个问题。但是现在我有 java.sql.BatchUpdateException: ASE has out of LOCKS... 我认为这更多的是关于服务器配置。

以上是关于java.sql.SQLException:将 Spark 数据帧保存到 Sybase 时找不到类型“TIMESTAMP”的主要内容,如果未能解决你的问题,请参考以下文章

java.sql.SQLException:架构“ROOT”不存在

java.sql.SQLException:Io 异常:在与 oracle 的 JDBC 连接期间从读取调用中得到减一

java.sql.SQLException: Io 异常: NL 异常产生

java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Invalid parameter binding(s)

java.sql.SQLException同时将变量从java传递到oracle过程

java.sql.SQLException: 无效的列类型: 1111