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)
    

      

  • 相关阅读:
    NVI模式
    C#----接口与多继承
    C#----接口与抽象类
    C#----接口的显式实现
    C# -- 继承规则
    MVC多层架构
    BootStrap2学习日记23---弹出对话框
    APP导航设计九法
    DevExpress Grid使用checkBox选中的方法
    遗漏的SQL语句
  • 原文地址:https://www.cnblogs.com/zhouwenyang/p/14600021.html
Copyright © 2011-2022 走看看