PySparkを使用して、データをSpark(v 1.3.0)データフレームのHiveテーブルに保存したいと思います。
ドキュメント の状態:
"spark.sql.Hive.convertMetastoreParquet:falseに設定すると、Spark SQLは、組み込みのサポートではなく、寄木細工のテーブルにHiveSerDeを使用します。"
Sparkチュートリアル を見ると、このプロパティを設定できるようです。
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ですぐに読み取れるようにするにはどうすればよいですか?
私はそこに行ったことがある...
APIはこれに関してちょっと誤解を招きます。
_DataFrame.saveAsTable
_はnotHiveテーブルを作成しますが、内部Sparkテーブルソース。
Hiveメタストアにも何かを保存しますが、意図したものではありません。
この 備考 はSpark 1.3に関してspark-userメーリングリストによって作成されました。
SparkからHiveテーブルを作成する場合は、次の方法を使用できます。
1。 SparkSQL for Hiveメタストアを介して_Create Table ...
_を使用します。
2。実際のデータにはDataFrame.insertInto(tableName, overwriteMode)
を使用します(Spark 1.3)
私は先週この問題にぶつかり、回避策を見つけることができました
ストーリーは次のとおりです。partitionByなしでテーブルを作成した場合、Hiveでテーブルを確認できます。
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;
問題は、Dataframe API(partitionBy + saveAsTable)を介して作成されたデータソーステーブルがHiveと互換性がないことです(これを参照 リンク )。 doc で提案されているようにspark.sql.Hive.convertMetastoreParquetをfalseに設定すると、SparkはデータをHDFSに配置するだけで、Hiveにテーブルを作成しません。 。次に、手動でHive Shellに移動して、データの場所を指す適切なスキーマとパーティションの定義を持つ外部テーブルを作成できます。 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で読み取ることができることです。