在Spark中使用jdbc驱动程序连接到Hive

wj8zmpe1  于 2022-12-12  发布在  Hive
关注(0)|答案(2)|浏览(424)

我需要使用Spark将数据从远程配置单元移动到本地配置单元。我尝试使用JDBC驱动程序连接到远程配置单元:'org.apache.hive.jdbc.HiveDriver'.我现在尝试从Hive读取数据,结果是列值中的列标题,而不是实际数据:

df = self.spark_session.read.format('JDBC') \
         .option('url', "jdbc:hive2://{self.host}:{self.port}/{self.database}") \
         .option('driver', 'org.apache.hive.jdbc.HiveDriver') \
         .option("user", self.username) \
         .option("password", self.password)
         .option('dbtable', 'test_table') \
         .load()
df.show()

结果:

+----------+
|str_column|
+----------+
|str_column|
|str_column|
|str_column|
|str_column|
|str_column|
+----------+

我知道ApacheSpark并不支持HiveJDBC,但是我已经找到了从其他不支持的资源下载的解决方案,比如IMBInformix。也许有人已经解决了这个问题。

vktxenjb

vktxenjb1#

调试并跟踪代码后,我们将在JdbcDialect中发现问题。由于没有HiveDialect,因此Spark将使用默认的JdbcDialect.quoteIdentifier。因此,您应该实现HiveDialect来解决此问题:

import org.apache.spark.sql.jdbc.JdbcDialect

class HiveDialect extends JdbcDialect{
  override def canHandle(url: String): Boolean = 
    url.startsWith("jdbc:hive2")
  

  override def quoteIdentifier(colName: String): String = {
    if(colName.contains(".")){
      var colName1 = colName.substring(colName.indexOf(".") + 1)
      return s"`$colName1`"
    }
    s"`$colName`"
  }
}

然后通过以下方式注册方言:

JdbcDialects.registerDialect(new HiveDialect)

最后,像这样在url中添加选项hive.resultset.use.unique.column.names=false

option("url", "jdbc:hive2://bigdata01:10000?hive.resultset.use.unique.column.names=false")

参见csdn blog

6qqygrtg

6qqygrtg2#

Apache Kyuubi在此处提供了一个Hive方言插件。https://kyuubi.readthedocs.io/en/latest/extensions/engines/spark/jdbc-dialect.html
Hive Dialect插件旨在为Spark的JDBC源提供Hive Dialect支持。它将自动注册到Spark并应用于url前缀为jdbc:hive2://jdbc:kyuubi://的JDBC源。它将以Hive SQL样式引用标识符,例如引用table. column中的table.column。
1.编译并从Kyuubi获得方言插件。(这是一个独立的Spark插件,独立于Kyuubi)
1.将jar放入$SPARK_HOME/jars
1.将插件添加到config spark.sql.extensions=org.apache.spark.sql.dialect.KyuubiSparkJdbcDialectExtension,它将自动注册到spark

相关问题