Вопрос:

Ошибка sqlContext HiveDriver в SQLException: метод не поддерживается

apache-spark jdbc hive pyspark hortonworks-data-platform

1026 просмотра

2 ответа

7771 Репутация автора

Я пытался использовать sqlContext.read.format("jdbc").options(driver="org.apache.hive.jdbc.HiveDriver")таблицу Hive в Spark без какого-либо успеха. Я провел исследование и прочитал ниже:

Как подключиться к серверу удаленного улья из спарка

Spark 1.5.1 не работает с кустом jdbc 1.2.0

http://belablotski.blogspot.in/2016/01/access-hive-tables-from-spark-using.html

Я использовал последнюю версию Hortonworks Sandbox 2.6 и задал сообществу такой же вопрос:

https://community.hortonworks.com/questions/156828/pyspark-jdbc-py4jjavaerror-calling-o95load-javasql.html?childToView=156936#answer-156936

То, что я хочу сделать, очень просто с помощью pyspark:

df = sqlContext.read.format("jdbc").options(driver="org.apache.hive.jdbc.HiveDriver", url="jdbc:hive2://localhost:10016/default", dbtable="sample_07",user="maria_dev", password="maria_dev").load()

Это дало мне эту ошибку:

17/12/30 19:55:14 INFO HiveConnection: Will try to open client transport with JDBC Uri: jdbc:hive2://localhost:10016/default
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/hdp/current/spark-client/python/pyspark/sql/readwriter.py", line 139, in load
    return self._df(self._jreader.load())
  File "/usr/hdp/current/spark-client/python/lib/py4j-0.9-src.zip/py4j/java_gateway.py", line 813, in __call__
  File "/usr/hdp/current/spark-client/python/pyspark/sql/utils.py", line 45, in deco
    return f(*a, **kw)
  File "/usr/hdp/current/spark-client/python/lib/py4j-0.9-src.zip/py4j/protocol.py", line 308, in get_return_value
py4j.protocol.Py4JJavaError: An error occurred while calling o119.load.
: java.sql.SQLException: Method not supported
at org.apache.hive.jdbc.HiveResultSetMetaData.isSigned(HiveResultSetMetaData.java:143)
at org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD$.resolveTable(JDBCRDD.scala:136)
at org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation.<init>(JDBCRelation.scala:91)
at org.apache.spark.sql.execution.datasources.jdbc.DefaultSource.createRelation(DefaultSource.scala:57)
at org.apache.spark.sql.execution.datasources.ResolvedDataSource$.apply(ResolvedDataSource.scala:158)
at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:119)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:231)
at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:381)
at py4j.Gateway.invoke(Gateway.java:259)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.GatewayConnection.run(GatewayConnection.java:209)
at java.lang.Thread.run(Thread.java:748)

С помощью билайн работает нормально

beeline> !connect jdbc:hive2://localhost:10016/default maria_dev maria_dev
Connecting to jdbc:hive2://localhost:10016/default
Connected to: Spark SQL (version 2.1.1.2.6.1.0-129)
Driver: Hive JDBC (version 1.2.1000.2.6.1.0-129)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://localhost:10016/default> select * from sample_07 limit 2;
+----------+-------------------------+------------+---------+--+
|   code   |       description       | total_emp  | salary  |
+----------+-------------------------+------------+---------+--+
| 00-0000  | All Occupations         | 134354250  | 40690   |
| 11-0000  | Management occupations  | 6003930    | 96150   |
+----------+-------------------------+------------+---------+--+

Я также мог бы сделать это:

spark = SparkSession.Builder().appName("testapp").enableHiveSupport().‌​getOrCreate()
spark.sql("select * from default.sample_07").collect()

Но это напрямую относится к метаданным улья. Я хотел бы использовать JDBC для Spark Thrift Server для детальной безопасности.

Я мог бы сделать PostgreSQL так:

sqlContext.read.format("jdbc").options(driver="org.postgresql.Driver")

Я также мог бы использовать Scala java.sql.{DriverManager, Connection, Statement, ResultSet}для создания JDBC-соединения в качестве клиентской части, чтобы добраться до Spark. Но это в основном помещает все данные в память, а затем заново создает Dataframe вручную.

Таким образом, вопрос заключается в следующем: есть ли способ создать информационный фрейм Spark с данными таблицы Hive без загрузки данных в память в клиент JDBC, такой как Scala, и не использовать SparkSession.Builder()подобные примеры выше? Мой пример использования - мне нужно иметь дело с детальной безопасностью.

Автор: HP. Источник Размещён: 04.01.2018 02:12

Ответы (2)


3 плюса

735 Репутация автора

Я не уверен, правильно ли я понимаю ваш вопрос или нет, но из того, что я понимаю, вам нужно будет поместить таблицу кустов во фрейм данных, для этого вам не нужно иметь соединение JDBC, в ваших примерах ссылок они пытаюсь подключиться к разным базам данных (RDBMS), а не к Hive.

Пожалуйста, ознакомьтесь с приведенным ниже подходом, используя улей-контекст, вы можете поместить таблицу во фрейм данных.

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.{DataFrame, SQLContext}

def main(args: Array[String]): Unit = {

val sparkConf = new SparkConf().setAppName("APPName")
    val sc = new SparkContext(sparkConf)
    val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
    val sqlContext = new SQLContext(sc)

val hive_df = hiveContext.sql("select * from schema.table").first()

//other way
// val hive_df= hiveContext.table ("SchemaName.TableName")

//Below will print the first line
df.first()
//count on dataframe
df.count()

}

Если вы действительно хотите использовать соединение JDBC, у меня есть следующий пример, который я использовал для базы данных Oracle, который может вам помочь.

val oracle_data = sqlContext.load("jdbc", Map("url" -> "jdbc:oracle:thin:username/password//hostname:2134/databaseName", "dbtable" -> "Your query tmp", "driver" -> "oracle.jdbc.driver.OracleDriver"));
Автор: roh Размещён: 08.01.2018 08:50

0 плюса

1833 Репутация автора

На самом деле я посмотрел на это. Hotornworks и cloudera прекращают поддержку для подключения к улью из Spark через Thrift Server.

Итак, вы работаете над чем-то, что невозможно.

https://www.cloudera.com/documentation/spark2/latest/topics/spark2_known_issues.html#ki_thrift_server .

Ссылки говорят, что экономия отключена, но это специально, чтобы улей от искры. Я могу подключиться ко всем типам баз данных от искры, кроме улья.

Таким образом, вы должны работать на другой стиль авторизации.

Поскольку искровой объект напрямую соединяется с ульем, они снимают опору для экономии.

Из вашего предыдущего вопроса, он может читать данные, но читает неправильные данные. Spark 2.2 Ошибка экономичного сервера на фрейме данных NumberFormatException при запросе таблицы Hive

Код

>>> df = sqlContext.read.format("jdbc").options(driver="org.apache.hive.jdbc.HiveDriver", url="jdbc:hive2://localhost:10016/default", dbtable="test4",user="hive", password="hive").option("fetchsize", "10").load()
>>> df.select("*").show()
+---+----+
| id|desc|
+---+----+
| id|desc|
| id|desc|
+---+----+

Проблема здесь в улье

По умолчанию в диалекте по умолчанию заключать в кавычки идентификаторы используют двойные кавычки. SQL-запрос, такой как SELECT «dw_date» FROM table…, будет проанализирован Hive для выбора строкового литерала вместо столбца с именем «dw_date». Заменив кавычки на обратные, похоже, проблема решена. Однако в моем тесте имена столбцов, полученные из Hive, начинаются с префикса с именем таблицы, например table.dw_date. Но вы не можете прямо обернуть назад галочки вокруг, как table.dw_date. Кроме того, нам нужно обернуть каждую часть в отдельности

код

import org.apache.spark.sql.jdbc.JdbcDialect
    private case object HiveDialect extends JdbcDialect {
      override def canHandle(url : String): Boolean = url.startsWith("jdbc:hive2")
      override def quoteIdentifier(colName: String): String = {
        colName.split(‘.’).map(part => s”`$part`”).mkString(“.”)
      }
    }

Пожалуйста, следуйте посту ниже, чтобы реализовать решение.

https://medium.com/@viirya/custom-jdbc-dialect-for-hive-5dbb694cc2bd

https://medium.com/@huaxing/customize-spark-jdbc-data-source-to-work-with-your-dedicated-database-dialect-beec6519af27

Зарегистрировать диалект

JdbcDialects.registerDialect(HiveDialect)

Тогда улей jdbc работает.

Автор: Achyuth Размещён: 09.02.2018 07:35
Вопросы из категории :
32x32