Spark操作Hive分割槽表
我的原創地址:https://dongkelun.com/2018/12/04/sparkHivePatition/
前言
前面學習總結了Hive分割槽表,現在學習總結一下Spark如何操作Hive分割槽表,包括利用Spark DataFrame建立Hive的分割槽表和Spark向已經存在Hive分割槽表裡插入資料,並記錄一下遇到的問題以及如何解決。
1、Spark建立分割槽表
只寫主要程式碼,完整程式碼見附錄
val data = Array(("001", "張三", 21, "2018"), ("002", "李四", 18, "2017"))
val df = spark.createDataFrame(data).toDF("id", "name", "age", "year")
//可以將append改為overwrite,這樣如果表已存在會刪掉之前的表,新建表
df.write.mode("append").partitionBy("year").saveAsTable("new_test_partition")
然後在Hive命令列裡看一下,新建的表是否有分割槽欄位year
用命令
desc new_test_partition;
或
show create table new_test_partition;
根據下面的結果可以看到新建的表確實有分割槽欄位year
hive> desc new_test_partition;
OK
id string
name string
age int
year string
# Partition Information
# col_name data_type comment
year string
Time taken: 0.432 seconds, Fetched: 9 row(s)
2、向已存在的表插入資料
2.1 Spark建立的分割槽表
- 這種情況其實和建表語句一樣就可以了
- 不需要開啟動態分割槽
df.write.mode("append").partitionBy("year").saveAsTable("new_test_partition")
當然也有其他方式插入資料,會在後面講到。
2.2 在Hive命令列建立的表
- 這裡主要指和Spark建立的表的檔案格式不一樣,Spark預設的檔案格式為PARQUET,為在命令列Hive預設的檔案格式為TEXTFILE,這種區別,也導致了異常的出現。
- 需要開啟動態分割槽
- 不開啟會有異常:
Exception in thread "main" org.apache.spark.SparkException: Dynamic partition strict mode requires at least one static partition column. To turn this off set hive.exec.dynamic.partition.mode=nonstrict
2.2.1 建表
用Hive分割槽表學習總結的建表語句建表(之前已經建過就不用重複建了)。
create table test_partition (
id string comment 'ID',
name string comment '名字',
age int comment '年齡'
)
comment '測試分割槽'
partitioned by (year int comment '年')
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;
2.2.2 異常
試著用上面的插入語句插入資料
df.write.mode("append").partitionBy("year").saveAsTable("test_partition")
丟擲異常
Exception in thread "main" org.apache.spark.sql.AnalysisException: The format of the existing table dkl.test_partition is `HiveFileFormat`. It doesn't match the specified format `ParquetFileFormat`.;
原因就是上面說的檔案格式不一致造成的。
2.2.3 解決辦法
用fomat指定格式
df.write.mode("append").format("Hive").partitionBy("year").saveAsTable("test_partition")
2.3 其他方法
df.createOrReplaceTempView("temp_table")
sql("insert into test_partition select * from temp_table")
df.write.insertInto("test_partition")
其中insertInto不需要也不能將df進行partitionBy,否則會丟擲異常
df.write.partitionBy("year").insertInto("test_partition")
Exception in thread "main" org.apache.spark.sql.AnalysisException: insertInto() can't be used together with partitionBy(). Partition columns have already be defined for the table. It is not necessary to use partitionBy().;
3、完整程式碼
package com.dkl.blog.spark.hive
import org.apache.spark.sql.SparkSession
/**
* 部落格:Spark操作Hive分割槽表
* https://dongkelun.com/2018/12/04/sparkHivePatition/
*
*/
object SparkHivePatition {
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("SparkHive")
.master("local")
.config("spark.sql.parquet.writeLegacyFormat", true)
.enableHiveSupport()
.getOrCreate()
import spark.sql
val data = Array(("001", "張三", 21, "2018"), ("002", "李四", 18, "2017"))
val df = spark.createDataFrame(data).toDF("id", "name", "age", "year")
//建立臨時表
df.createOrReplaceTempView("temp_table")
//切換hive的資料庫
sql("use dkl")
// 1、建立分割槽表,可以將append改為overwrite,這樣如果表已存在會刪掉之前的表,新建表
df.write.mode("append").partitionBy("year").saveAsTable("new_test_partition")
//2、向Spark建立的分割槽表寫入資料
df.write.mode("append").partitionBy("year").saveAsTable("new_test_partition")
sql("insert into new_test_partition select * from temp_table")
df.write.insertInto("new_test_partition")
//開啟動態分割槽
sql("set hive.exec.dynamic.partition.mode=nonstrict")
//3、向在Hive裡用Sql建立的分割槽表寫入資料,丟擲異常
// df.write.mode("append").partitionBy("year").saveAsTable("test_partition")
// 4、解決方法
df.write.mode("append").format("Hive").partitionBy("year").saveAsTable("test_partition")
sql("insert into test_partition select * from temp_table")
df.write.insertInto("test_partition")
//這樣會丟擲異常
// df.write.partitionBy("year").insertInto("test_partition")
spark.stop
}
}
相關閱讀
相關文章
- Hive和Spark分割槽策略HiveSpark
- INTERVAL分割槽表鎖分割槽操作
- hive 分割槽表和分桶表區別Hive
- hive 動態分割槽插入資料表Hive
- 分割槽表attach detach操作
- 分割槽表的常用操作
- hive學習筆記之四:分割槽表Hive筆記
- Hive動態分割槽Hive
- hive中的表、外部表、分割槽和桶的理解Hive
- 全面學習分割槽表及分割槽索引(17)--其它索引分割槽管理操作索引
- 關於分割槽表的操作
- Sql Server系列:分割槽表操作SQLServer
- HIVE基本語法以及HIVE分割槽Hive
- Hive的靜態分割槽與動態分割槽Hive
- [Hive]hive分割槽設定注意事項Hive
- Spark SQL解析查詢parquet格式Hive表獲取分割槽欄位和查詢條件SparkSQLHive
- oracle 分割槽表進行shrink操作Oracle
- 關於分割槽表的move操作
- SQL Server表分割槽操作詳解SQLServer
- ORACLE分割槽表的概念及操作Oracle
- ORACLE分割槽表的操作應用Oracle
- oracle 分割槽表 概念以及常用操作Oracle
- 表分割槽操作大全_table partitioning
- oracle分割槽表和分割槽表exchangeOracle
- spark2.2.0 配置spark sql 操作hiveSparkSQLHive
- MySql資料分割槽操作之新增分割槽操作MySql
- Hive中靜態分割槽和動態分割槽總結Hive
- Hive動態分割槽詳解Hive
- 全面學習分割槽表及分割槽索引(13)--分隔表分割槽索引
- oracle分割槽表和非分割槽表exchangeOracle
- 分割槽表split操作及maxvalue處理
- 關於分割槽表的概念及操作
- Hive學習筆記 3 Hive的資料模型:內部表、分割槽表、外部表、桶表、檢視Hive筆記模型
- Oracle分割槽表及分割槽索引Oracle索引
- 全面學習分割槽表及分割槽索引(9)--刪除表分割槽索引
- 全面學習分割槽表及分割槽索引(11)--合併表分割槽索引
- 全面學習分割槽表及分割槽索引(12)--修改list表分割槽索引
- 學習筆記】分割槽表和分割槽索引——新增表分割槽(二)筆記索引