сохранить Spark dataframe в Hive: таблица не читается, потому что " паркет не является последовательным файлом"

Я хотел бы сохранить данные в фрейме данных Spark (v 1.3.0) в таблицу Hive с помощью PySpark.

на документация гласит:

смотреть на!--13-->Искра учебник представляется, что это свойство может быть установлено:

from pyspark.sql import HiveContext

sqlContext = HiveContext(sc)
sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")

# code to create dataframe

my_dataframe.saveAsTable("my_dataframe")

однако, когда я пытаюсь запрос сохраненной таблицы в Hive возвращает:

hive> select * from my_dataframe;
OK
Failed with exception java.io.IOException:java.io.IOException: 
hdfs://hadoop01.woolford.io:8020/user/hive/warehouse/my_dataframe/part-r-00001.parquet
not a SequenceFile

Как сохранить таблицу, чтобы она сразу читалась в Hive?

3 ответов


Я был там...
API немного вводит в заблуждение на этом.
DataFrame.saveAsTable тут не создайте таблицу улья, но внутренний источник таблицы Spark.
Он также хранит что-то в куст метахранилища, но не то, что вы хотите.
Это Примечание был сделан spark - пользователь список рассылки относительно Spark 1.3.

Если вы хотите создать таблицу улья из Spark, вы можете использовать следующий подход:
1. Использовать Create Table ... через SparkSQL для Hive метастор.
2. Использовать DataFrame.insertInto(tableName, overwriteMode) для фактических данных (Spark 1.3)


я попал в эту проблему на прошлой неделе и смог найти обходной путь

вот история: Я могу видеть таблицу в Hive, если я создал таблицу без partitionBy:

spark-shell>someDF.write.mode(SaveMode.Overwrite)
                  .format("parquet")
                  .saveAsTable("TBL_HIVE_IS_HAPPY")

hive> desc TBL_HIVE_IS_HAPPY;
      OK
      user_id                   string                                      
      email                     string                                      
      ts                        string                                      

но Hive не может понять схему таблицы(схема пуста...) если я сделаю это:

spark-shell>someDF.write.mode(SaveMode.Overwrite)
                  .format("parquet")
                  .saveAsTable("TBL_HIVE_IS_NOT_HAPPY")

hive> desc TBL_HIVE_IS_NOT_HAPPY;
      # col_name                data_type               from_deserializer  

[решение]:

spark-shell>sqlContext.sql("SET spark.sql.hive.convertMetastoreParquet=false")
spark-shell>df.write
              .partitionBy("ts")
              .mode(SaveMode.Overwrite)
              .saveAsTable("Happy_HIVE")//Suppose this table is saved at /apps/hive/warehouse/Happy_HIVE


hive> DROP TABLE IF EXISTS Happy_HIVE;
hive> CREATE EXTERNAL TABLE Happy_HIVE (user_id string,email string,ts string)
                                       PARTITIONED BY(day STRING)
                                       STORED AS PARQUET
                                       LOCATION '/apps/hive/warehouse/Happy_HIVE';
hive> MSCK REPAIR TABLE Happy_HIVE;

проблема в том, что таблица источников данных, созданная через API Dataframe(partitionBy+saveAsTable), несовместима с ульем.(см. ссылке). Установив Искра.язык SQL.улей.convertMetastoreParquet false, как предложено в doc, Spark только помещает данные в HDFS, но не создает таблицу на Hive. И затем вы можете вручную перейти в оболочку hive, чтобы создать внешнюю таблицу с правильной схемой и определением раздела, указывающим на местоположение данных. Я тестировал это в Spark 1.6.1, и это сработало для меня. Надеюсь, это поможет!


Я сделал в pyspark, spark версии 2.3.0:

создать пустую таблицу, где нам нужно сохранить/перезаписать данные, такие как:

create table databaseName.NewTableName like databaseName.OldTableName;

затем выполните следующую команду:

df1.write.mode("overwrite").partitionBy("year","month","day").format("parquet").saveAsTable("databaseName.NewTableName");

проблема в том, что вы не можете прочитать эту таблицу с помощью hive, но вы можете читать с помощью spark.