从 Spark Sql 写入 Hive 表时出错

Aya*_*was 0 hive apache-spark

我正在尝试从 Spark Sql 将数据插入到 Hive 外部表中。我通过以下命令创建了 hive 外部表

CREATE EXTERNAL TABLE  tab1 ( col1 type,col2 type ,col3 type) CLUSTERED BY (col1,col2) SORTED BY (col1) INTO 8 BUCKETS STORED AS PARQUET
Run Code Online (Sandbox Code Playgroud)

在我的 spark job 中,我编写了以下代码 Dataset df = session.read().option("header","true").csv(csvInput);

df.repartition(numBuckets, somecol)
                  .write()
                  .format("parquet")
                  .bucketBy(numBuckets,col1,col2)
                  .sortBy(col1)
                  .saveAsTable(hiveTableName);
Run Code Online (Sandbox Code Playgroud)

每次运行此代码时,都会出现以下异常

org.apache.spark.sql.AnalysisException: Table `tab1` already exists.;
    at org.apache.spark.sql.DataFrameWriter.saveAsTable(DataFrameWriter.scala:408)
    at org.apache.spark.sql.DataFrameWriter.saveAsTable(DataFrameWriter.scala:393)
    at somepackage.Parquet_Read_WriteNew.writeToParquetHiveMetastore(Parquet_Read_WriteNew.java:100)
Run Code Online (Sandbox Code Playgroud)

bob*_*bob 6

您应该在 hive 中保存数据时指定保存模式。

\n\n
df.write.mode(SaveMode.Append)\n              .format("parquet")\n              .bucketBy(numBuckets,col1,col2)\n              .sortBy(col1)\n              .insertInto(hiveTableName);\n
Run Code Online (Sandbox Code Playgroud)\n\n

Spark提供以下几种保存模式:

\n\n

保存模式

\n\n

ErrorIfExists:如果目标已经存在,则抛出异常。如果目标不存在\xe2\x80\x99t 则写出数据。

\n\n

Append:如果目标已经存在,则将数据附加到它。如果数据不存在,则将数据写出。

\n\n

Overwrite:如果目标已经存在,则删除该目标。把数据写出来。

\n\n

Ignore:如果目标已经存在,则默默地跳过写出。否则写出数据。

\n


Ami*_*mar 5

您正在使用saveAsTableAPI,它将表创建到 Hive 中。由于您已经通过命令创建了 hive 表,因此该表tab1已经存在。所以当 Spark API 尝试创建它时,它会抛出错误,说表已经存在,org.apache.spark.sql.AnalysisException: Tabletab1already exists.

要么删除表,让 spark APIsaveAsTable自己创建表。或者使用 APIinsertInto插入到现有的 hive 表中。

df.repartition(numBuckets, somecol)
                  .write()
                  .format("parquet")
                  .bucketBy(numBuckets,col1,col2)
                  .sortBy(col1)
                  .insertInto(hiveTableName);
Run Code Online (Sandbox Code Playgroud)