2015-07-17 26 views
7

PySpark kullanarak bir Spark (v 1.3.0) veri çerçevesini bir Hive tablosuna kaydetmek istiyorum.kaydet Spark veri çerçevesini Hive: tablo "okunabilir bir SequenceFile değil"

documentation devletler:

"spark.sql.hive.convertMetastoreParquet: false olarak ayarlandığında, SQL desteği yerleşik yerine parke tablolar için kovan serde kullanacağı Spark."

Spark tutorial baktığımızda, bu özellik ayarlanabilir görünüyor:

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") 

Ancak, bu döndüren Hive kaydedilen tabloyu sorgulamak çalıştığınızda:

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 

nasıl Tabloyu, Hive'de hemen okunabilmesi için kaydeder miyim?

cevap

14

Orada bulundum ...
API bu konuda yanıltıcıdır.
DataFrame.saveAsTable değil bir Hive tablosu oluşturmak, ancak bir iç Spark tablo kaynağı.
Ayrıca bir şeyi Hive metastore'a depolar, ancak ne niyetinde değilsiniz.
Bu remark, Spark 1.3 ile ilgili kıvılcım kullanıcı posta listesi tarafından yapılmıştır. Kovan metastore için SparkSQL aracılığıyla
1. kullanın Create Table ...: Eğer Kıvılcım bir kovan tablo oluşturmak isterseniz

, bu yaklaşımı kullanabilirsiniz. Gerçek veriler için
2. DataFrame.insertInto(tableName, overwriteMode) (1.3 Spark)

2

geçen hafta bu konuyu vurmak ve bir geçici çözüm İşte

bulabildim hikaye: benim yarattığım eğer Hive tablo görebilirsiniz partitionBy olmadan tablosu:

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 
01:

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          

Ama Kovanı (şema ... boş) eğer bunu yaparsam tablo şema anlayamıyorum

[Çözüm]:

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; 

sorun Dataframe API (partitionBy + saveAsTable) vasıtasıyla oluşturulmuş bir veri kaynağı tablo kovanı ile uyumlu değildir (bu link bakınız).. spark.sql.hive.convertMetastoreParquet öğesinin doc numaralı belgede önerildiği gibi yanlış ayarlanmasıyla, Spark yalnızca verileri HDFS'ye koyar, ancak Hive'da tablo oluşturmaz. Ve sonra el ile veri kümesine uygun şema & bölüm tanımı ile harici bir tablo oluşturmak için kovanın içine girebilirsiniz. Bunu Spark 1.6.1'de test ettim ve benim için çalıştı. Umarım bu yardımcı olur!

+2

Tam olarak aynı cevabı yazdınız [burada] (http://stackoverflow.com/questions/31341498/save-spark-dataframe-as-dynamic-partitioned-table-in-hive/37504196#37504196).Eğer sorunun bir kopya olduğunu düşünüyorsanız, bu şekilde işaretlemeli ve aynı cevabı iki kez imo etmemelisiniz. – Jaap

+2

TBL_HIVE_IS_NOT_HAPPY ve TBL_HIVE_IS_HAPPY kodunun aynısı olduğu görülüyor. Bir şey mi eksik? –