Spark SQLを使用してHiveテーブルを読み取り、それをscala valに割り当てます
val x = sqlContext.sql("select * from some_table")
次に、データフレームxを使用していくつかの処理を行い、最後にデータフレームyを作成します。これには、テーブルsome_tableとまったく同じスキーマがあります。
最後に、yデータフレームを同じHiveテーブルsome_tableに上書きして挿入しようとしています
y.write.mode(SaveMode.Overwrite).saveAsTable().insertInto("some_table")
次に、エラーが発生します
org.Apache.spark.sql.AnalysisException:読み取り中のテーブルに上書きを挿入できません
Sql挿入ステートメントを作成してsqlContext.sql()を使用して起動しようとしましたが、同じエラーが発生しました。
このエラーを回避する方法はありますか?同じテーブルにレコードを挿入する必要があります。
こんにちは私は提案どおりにやってみましたが、それでも同じエラーが発生します。
val x = sqlContext.sql("select * from incremental.test2")
val y = x.limit(5)
y.registerTempTable("temp_table")
val dy = sqlContext.table("temp_table")
dy.write.mode("overwrite").insertInto("incremental.test2")
scala> dy.write.mode("overwrite").insertInto("incremental.test2")
org.Apache.spark.sql.AnalysisException: Cannot insert overwrite into table that is also being read from.;
最初にDataFrame y
を一時テーブルに保存する必要があります
y.write.mode("overwrite").saveAsTable("temp_table")
次に、ターゲットテーブルの行を上書きできます
val dy = sqlContext.table("temp_table")
dy.write.mode("overwrite").insertInto("some_table")
実際には、チェックポイントを使用してこれを実現することもできます。データ系統を破壊するため、Sparkは、同じテーブルで読み取りおよび上書きしていることを検出できません。
sqlContext.sparkContext.setCheckpointDir(checkpointDir)
val ds = sqlContext.sql("select * from some_table").checkpoint()
ds.write.mode("overwrite").saveAsTable("some_table")
Spark 2.2
'spark.sql.partitionProvider' 'spark.sql.sources.provider' 'spark.sql.sources.schema.numPartCols' spark.sql.sources.schema.numParts '' spark.sql.sources.schema.part.0 ' 'spark.sql.sources.schema.part.1' 'spark.sql.sources.schema.part.2' 'spark.sql.sources.schema.partCol.0' 'spark.sql.sources.schema.partCol。 1 '
https://querydb.blogspot.com/2019/07/read-from-Hive-table-and-write-back-to.html
スパークでHiveテーブルからデータを読み取ります。
val hconfig = new org.Apache.hadoop.conf.Configuration()
org.Apache.Hive.hcatalog.mapreduce.HCatInputFormat.setInput(hconfig , "dbname", "tablename")
val inputFormat = (new HCatInputFormat).asInstanceOf[InputFormat[WritableComparable[_],HCatRecord]].getClass
val data = sc.newAPIHadoopRDD(hconfig,inputFormat,classOf[WritableComparable[_]],classOf[HCatRecord])
最初に、DataFrame y
を寄木細工のファイルのように保存する必要があります。
y.write.parquet("temp_table")
これをロードした後:
val parquetFile = sqlContext.read.parquet("temp_table")
最後に、データをテーブルに挿入します
parquetFile.write.insertInto("some_table")