zoukankan      html  css  js  c++  java
  • 【spark】sparkJDBC自定义方言(以vertica为例)

    背景

    sparkJDBC在写入时提供了overwrite模式。当写入数据之前,会将之前的表drop掉,然后根据DataFrame类型推断生成Create语句新建一张表。

    在某些小众的数据库,spark内部没有提供对应的方言。这是spark会使用一个NoopCommon的默认方言,这时候很容易推断错误。

    案例

    以vertica为例,在DataFrame中包含String类型时,如下:

    root
     |-- time: timestamp (nullable = true)
     |-- AMP: double (nullable = true)
     |-- NOZP: integer (nullable = true)
     |-- value: integer (nullable = true)
     |-- reason: string (nullable = true)
    

    这时在直接用jdbc写入时会报

    java.sql.SQLSyntaxErrorException: [Vertica][VJDBC](5108) ERROR: Type "TEXT" does not exist
    

    因此需要注册一个vertica方言,将String类型转为一个合适varchar类型。如下

    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里面

    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中注册方言

    JdbcDialects.registerDialect(VerticaDialect)
    

      

  • 相关阅读:
    Python正则表达式指南
    Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)
    Python中的urlparse、urllib抓取和解析网页(一)
    __name__ = '__main__'
    odoo context
    Python xlwt模块
    python中使用xlrd、xlwt操作excel
    odoo 下 get_object_reference 函数
    Python运算符
    jQuery实现contains方法不区分大小写的方法教程
  • 原文地址:https://www.cnblogs.com/zhouwenyang/p/14600021.html
Copyright © 2011-2022 走看看