最近使用spark jdbc寫關(guān)系庫數(shù)據(jù)庫 用的是Overwrite模式,發(fā)現(xiàn)字段類型被重建為 TEXT拍冠。
為了使Spark不修改表原本的類型,我們讓Overwrite操作采用truncate table的方式而不是重建表
查看官方文檔后看到 truncate 屬性
image
在options中設(shè)置了truncate屬性后 發(fā)現(xiàn)仍未解決問題
代碼如下:
val options = Map(
"url" -> url,
"driver" -> driverClass,
"user" -> user,
"password" -> password,
"dbtable" -> tableName,
"truncate" -> "true")
df.write.mode(SaveMode.Overwrite).format("jdbc").options(options).save()
查看源碼:
image.png
isTruncate就是我們配置的truncate屬性了
后面的isCascadingTruncateTable(url) 是判斷數(shù)據(jù)庫是否支持truncate操作历极。
繼續(xù)看:
image.png
image.png
原來是在這里根據(jù)url 來匹配Spark適配的JdbcDialect
而Spark并未適配我們使用的informix數(shù)據(jù)庫 所以truncate屬性并不生效
解決方案:
1灼卢、適配informix數(shù)據(jù)庫
object InformixDialect extends JdbcDialect {
override def canHandle(url:String):Boolean = url.startsWith("jdbc:informix")
override def isCascadingTruncateTable(): Option[Boolean] =Some(false)
override def getJDBCType(dt: DataType): Option[JdbcType] = dt match {
case StringType =>Option(JdbcType("VARCHAR(128)", java.sql.Types.VARCHAR))
}
}
canHandle: 適配jdbc url
isCascadingTruncateTable: 支持truncate操作,這里需要設(shè)置為false 才支持truncat∮凶桑⊙Д⊙
getJDBCType: 映射jdbcType 和 sqlType 用來支持建表操作
2赦颇、注冊方言
JdbcDialects.registerDialect(InformixDialect)
3二鳄、寫庫
val options = Map(
"url" -> url,
"driver" -> driverClass,
"user" -> user,
"password" -> password,
"dbtable" -> tableName,
"truncate" -> "true")
df.write.mode(SaveMode.Overwrite).format("jdbc").options(options).save()
成功寫入 并不會對表字段產(chǎn)生影響。