問題重現(例)
當我將數據存儲格式改變,或者增加一列的時候,我習慣使用了alter table add …來實現
原來的表:
ALTER TABLE test ADD COLUMNS (weight STRING) CASCADE
加上一列weight字段後(這裏使用cascade就是爲了同步到hivemetastore),我用spark向表插入一個帶有weight字段的表,此時拋出異常
Exception in thread "main" org.apache.spark.sql.AnalysisException:
The column number of the existing table default.test(struct<age:string,tall:string,name:string>)
doesn't match the data schema(struct<age:string,name:string,tall:string,weight:string>);
告訴我字段不匹配,於是我去找了元數據發現元數據中的確沒有weight這一字段,難道是cascade失效了?不太可能
差元數據的步驟:
use hivemetastore;
select * from TBLS;//找到此表的TBL_ID
//找到後在TABLE_PARAMS找這張表的schema
select * from TABLE_PARAMS where TBL_ID = '691'
發現的確沒有改變
於是去網上尋求答案
在Spark社區21841中發現了原因
原因及解決
原因就在於我們的存儲格式爲parquet
parquet格式時,spark會直接從上面的元數據庫中尋找schema信息,但是此種格式下,hive中通過alter的方式並不能修改元數據庫中的信息,所以更新就失敗了,spark訪問也無效
解決:
粗劣的解決辦法就是update元數據庫中的這一條信息,但是比較費時,
也可以將parquet格式改掉,用hive的格式也可以同步,我們因爲採用parquet存儲信息
所以不能輕易改變,目前只能update元數據庫來實現,苦逼,如果有更好的方法,請隨時評論給我