【spark】sparkJDBC自定义方言(以vertica为例)
背景
sparkJDBC在写入时提供了overwrite模式。当写入数据之前,会将之前的表drop掉,然后根据DataFrame类型推断生成Create语句新建一张表。
在某些小众的数据库,spark内部没有提供对应的方言。这是spark会使用一个NoopCommon的默认方言,这时候很容易推断错误。
案例
以vertica为例,在DataFrame中包含String类型时,如下:
1 2 3 4 5 6 | root |-- time : timestamp (nullable = true ) |-- AMP : double (nullable = true ) |-- NOZP : integer (nullable = true ) |-- value : integer (nullable = true ) |-- reason : string (nullable = true ) |
这时在直接用jdbc写入时会报
1 | java.sql.SQLSyntaxErrorException : [Vertica][VJDBC]( 5108 ) ERROR : Type "TEXT" does not exist |
因此需要注册一个vertica方言,将String类型转为一个合适varchar类型。如下
1 2 3 4 5 6 7 8 9 10 | object VerticaDialect extends JdbcDialect { override def canHandle(url : String) : Boolean = { url.toLowerCase(Locale.ROOT).startsWith( "jdbc:vertica" ) } override def getJDBCType(dt : DataType) : Option[JdbcType] = dt match { case StringType = > Some(JdbcType( "LONG VARCHAR" , Types.LONGVARCHAR)) case _ = > None } } |
因为String是无界的,所以转为long varchar最为保险。这里只需要转String类型即可,因为在JdbcUtils里面
1 2 3 4 | private def getJdbcType(dt : DataType, dialect : JdbcDialect) : JdbcType = { dialect.getJDBCType(dt).orElse(getCommonJDBCType(dt)).getOrElse( throw new IllegalArgumentException(s "Can't get JDBC type for ${dt.catalogString}" )) } |
sparkJDBC会优先找注册的方言,然后还会在CommonJDBCType中找一次。所以其他通用的类型不需要在方言中重复指定。
最后在driver中注册方言
1 | JdbcDialects.registerDialect(VerticaDialect) |
标签:
spark
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端