Чтение представления улья, созданного с помощью CTE (с предложением) из spark

#apache-spark #hadoop #hive #apache-spark-sql #hiveql

#apache-spark #hadoop #улей #apache-spark-sql #hiveql

Вопрос:

У меня есть представление в Hive, созданное с помощью CTE (с предложением), которое объединяет две таблицы, затем вычисляет, чтобы отобразить только самую последнюю запись для каждого идентификатора. В моем env у меня есть инструмент для просмотра баз данных hive (DBeaver, обязательный для разработчиков, не использующих datalake, для просмотра данных).

Просмотр кода

     CREATE VIEW IF NOT EXISTS db.test_cte_view AS
      with cte as (select * from db.test_cte union select * from db.test_cte_2),
       tmp as (SELECT id, idate, ROW_NUMBER() over(PARTITION BY id ORDER BY idate desc ) AS row_num from cte)
      SELECT cte.* from cte
         join (SELECT * from tmp where tmp.row_num =1) tmp_2
         on cte.id = tmp_2.id
         and cte.idate = tmp_2.idate
  

Проблема в том:

когда представление создается через beeline

(Это наш основной способ создания таблиц и представлений в Hive)
Я могу легко просматривать DBeaver, но при запуске процесса spark для чтения из него происходит сбой со следующим:

     ##pyspark
    spark.sql("select * from db.test_cte_view").show()

    'Table or view not found: cte; line 3 pos 56'
    Traceback (most recent call last):
    File "DATA/fs3/hadoop/yarn/local/usercache/ingouagn/appcache/application_1552132357519_15102/container_e378_1552132357519_15102_01_000001/pyspark.zip/pyspark/sql/session.py", line 545, in sql
      return DataFrame(self._jsparkSession.sql(sqlQuery), self._wrapped)
    File "/DATA/fs3/hadoop/yarn/local/usercache/ingouagn/appcache/application_1552132357519_15102/container_e378_1552132357519_15102_01_000001/py4j-0.10.4-src.zip/py4j/java_gateway.py", line 1133, in __call__
      answer, self.gateway_client, self.target_id, self.name)
    File "/DATA/fs3/hadoop/yarn/local/usercache/ingouagn/appcache/application_1552132357519_15102/container_e378_1552132357519_15102_01_000001/pyspark.zip/pyspark/sql/utils.py", line 69, in deco
      raise AnalysisException(s.split(': ', 1)[1], stackTrace)
    pyspark.sql.utils.AnalysisException: 'Table or view not found: cte; line 3 pos 56'
  

Когда представление создается с помощью sparl.sql («СОЗДАТЬ ПРЕДСТАВЛЕНИЕ КАК …»)

Я могу хорошо прочитать его с

     ##pyspark
    spark.sql("select * from db.test_cte_view").show()
  

Но при попытке просмотра с помощью DBeaver происходит сбой с чем-то вроде:

 Query execution failed

Reason:
SQL Error [40000] [42000]: Error while compiling statement: FAILED: SemanticException line 1:330 Failed to recognize predicate 'UNION'. Failed rule: 'identifier' in subquery source in definition of VIEW test_cte_view [
SELECT `gen_attr_0` AS `id`, `gen_attr_1` AS `status`, `gen_attr_2` AS `idate` FROM (SELECT `gen_attr_0`, `gen_attr_1`, `gen_attr_2` FROM ((SELECT `gen_attr_0`, `gen_attr_1`, `gen_attr_2` FROM (SELECT `id` AS `gen_attr_0`, `status` AS `gen_attr_1`, `idate` AS `gen_attr_2` FROM `db`.`test_cte`) AS gen_subquery_0) UNION DISTINCT (SELECT `gen_attr_5`, `gen_attr_6`, `gen_attr_7` FROM (SELECT `id` AS `gen_attr_5`, `status` AS `gen_attr_6`, `idate` AS `gen_attr_7` FROM `db`.`test_cte_2`) AS gen_subquery_1)) AS cte INNER JOIN (SELECT `gen_attr_3`, `gen_attr_4`, `gen_attr_8` FROM (SELECT `gen_attr_3`, `gen_attr_4`, `gen_attr_8` FROM (SELECT gen_subquery_4.`gen_attr_3`, gen_subquery_4.`gen_attr_4`, row_number() OVER (PARTITION BY `gen_attr_3` ORDER BY `gen_attr_4` DESC NULLS LAST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS `gen_attr_8` FROM (SELECT `gen_attr_3`, `gen_attr_4` FROM ((SELECT `gen_attr_3`, `gen_attr_9`, `gen_attr_4` FROM (SELECT `id` AS `gen_attr_3`, `status` AS `gen_attr_9`, `idate` AS `gen_attr_4` FROM `db`.`test_cte`) AS gen_subquery_2) UNION DISTINCT (SELECT `gen_attr_5`, `gen_attr_6`, `gen_attr_7` FROM (SELECT `id` AS `gen_attr_5`, `status` AS `gen_attr_6`, `idate` AS `gen_attr_7` FROM `db`.`test_cte_2`) AS gen_subquery_3)) AS cte) AS gen_subquery_4) AS gen_subquery_5) AS tmp WHERE (`gen_attr_8` = 1)) AS tmp_2 ON ((`gen_attr_0` = `gen_attr_3`) AND (`gen_attr_2` = `gen_attr_4`))) AS cte
] used as test_cte_view at Line 1:14
  

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

Есть ли способ заставить первый сценарий (создание представления через beeline и доступ к нему через spark sql) работать?

Спасибо.

spark: 2.1.1, Hive: 1.2.1

Таблицы

      CREATE TABLE db.test_cte(
      id int, 
      status string, 
      idate date )
  
     CREATE TABLE db.test_cte_2(
      id int, 
      status string, 
      idate date )
  

заполнено:

       insert into db.test_cte values
      (1,"green","2019-03-08"),
      (2,"green","2019-03-08"),
      (3,"green","2019-03-08"),
      (1,"red","2019-03-09"),
      (1,"yellow","2019-03-10"),
      (2,"gray","2019-03-09")
  
      insert into db.test_cte_2 values
      (10,"green","2019-03-08"),
      (20,"green","2019-03-08"),
      (30,"green","2019-03-08"),
      (10,"red","2019-03-09"),
      (10,"yellow","2019-03-10"),
      (20,"gray","2019-03-09")
  

Редактировать:
Для всех, кому интересно, я создал проблему в Spark JIRA:
https://issues.apache.org/jira/browse/SPARK-27203

Комментарии:

1. 1-я проблема, о которой вы упомянули ‘Таблица или представление не найдены: cte; строка 3 поз. 56’, должна быть spark.sql («выбрать * из db.test_cte_view»).show() 2.СБОЙ: SemanticException строка 1: 330 Не удалось распознать предикат ‘UNION’ Это, похоже, чисто проблема Dbever (запрос работает в spark-sql) проверьте, можете ли вы использовать union all вместо union

2. @rbyndoor извините, я не понял вашего первого пункта. Что касается второго момента, я не могу изменить SQL-код, сгенерированный spark при выполнении инструкции create view, но изменение union на union all в коде view не устраняет проблему

3. Я попробовал ваш приведенный выше пример. 1-я проблема я не вижу никакого представления create для dev_app_gvr_grover.test_cte_view 2-я проблема работала непосредственно в оболочке spark-sql, поэтому, должно быть, проблема только в DbEver

4. ах, да, я виноват … для первой проблемы я действительно отредактирую сообщение (но проблема все еще остается). Во-вторых, да, это хорошо работает в spark-shell и с сеансом spark. Мне было интересно, есть ли конфигурация или какой-либо другой способ настроить генератор кода spark SQL, чтобы он генерировал код, который может быть интерпретирован beeline

Ответ №1:

Я столкнулся с той же проблемой с Spark2.1.1.2.6.1.0-129. Обновление до Spark2.4 решило проблему.

Если обновление невозможно, это обходное решение помогло мне в версии 2.1:

 spark.table("db.my_view_with_ctes").registerTempTable("tmp")
spark.sql("select * from tmp")
  

Это выполняется значительно дольше, чем чтение представления через spark-sql в Spark2.4 (более чем в 10 раз больше времени выполнения для моего варианта использования), но это работает.