解決hive中導入text文件遇到的坑
今天幫一同學導入一個excel數據,我把excel保存為txt格式,然後建表導入,失敗!分隔符格式不匹配,無法導入!!!!怎麼看兩邊都是\t,怎麼不匹配呢?
做為程序員,最不怕的就是失敗,因為我們有一顆勇敢的心!再來!又特麼失敗。。。
想瞭好久,看看瞭看我的表格式,我犯瞭一個好低級的錯誤:
hive表的存儲格式設置為瞭orcfile!!!
眾所周知:orcfile為壓縮格式,可以節約大量存儲空間,但orc還有個特點就是不能直接load數據!要想load數據,我們要建一個存儲格式為textfile的中間表,然後再把數據抽取過去。因為這個錯誤太簡單,網上有相關科普,因此很少有把它當錯誤寫出來。遇到問題的朋友們可能要走些彎路,我來補個漏~~~~~~
舉個栗子:
1.首先,導出excel表格為txt格式,(這個過程不再贅述,網上教程一大把)。
123,小明,666,1990-09-23 12:00:18 256,小夥,555,1989-10-06 03:57:32 142,小蘭,444,1992-07-04 05:05:45
2.在hive中創建表模型:
CREATE TABLE IF NOT EXISTS STUDENTS ( ID INT COMMENT'學生', SNAME STRING COMMENT '姓名', SCORE INT COMMENT '得分', STIME STRING COMMENT '考試時間' ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS ORCFILE;
3.創建臨時表(中間表):
CREATE TABLE IF NOT EXISTS STUDENTS_TMP ( ID INT COMMENT'學生', SNAME STRING COMMENT '姓名', SCORE INT COMMENT '得分', STIME STRING COMMENT '考試時間' ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;
與目標表隻有名稱和存儲格式不同,其他都相同。
4.load 數據到臨時表:
load data local inpath '/export/data/1.txt' into table students_tmp;
5.將數據導入目標表:
insert overwrite table students select * from students_tmp;
6.然後查看表數據,大功造成:
hive > select * from students; OK 123 小明 666 1990-09-23 12:00:18 256 小夥 555 1989-10-06 03:57:32 142 小蘭 444 1992-07-04 05:05:45 Time taken: 0.26 seconds, Fetched: 3 row(s)
其他存儲格式如 SEQUENCEFILE、PARQUET 等,也要選存儲為textfile格式,然後抽入目標表。
一定要按照導出格式的分隔符建表,不然load數據必然出錯或全是null;
excel導出格式:
格式 分隔符 中文名稱 text \t 制表符 csv , 逗號
7.還要註意一點是我們從excel導出的文件格式是gb2312 (無論是txt還是csv都是這個格式,都需要轉碼),我們需要把它轉成utf-8才能Load。
所以在load之前,我們一般會采取兩種辦法:
1. 在文本編輯器中進行轉碼,帶不帶bom關系不大,然後上傳;
2.在文件所在本地目錄下執行以下命令轉碼:
piconv -f gb2312 -t UTF-8 1.txt > 2.txt
註意,在本地目錄下命令轉碼會改變文件名,因為此命令會把所文件寫入到另一個文件,並清空原文件內容,如果我們不改名,文件內容會完全丟失。所以,我們Load的時候一定要選擇修改後的文件名哦。
示例:
轉碼前數據:
hive> select * from students; OK 112 С�� 35 2017/8/19 15:30 113 ���� 45 114 ³�� 55 2017/8/21 15:30 115 ���� NULL 116 ������ 75 2017/8/23 15:30 117 ������ 85 2017/8/24 15:30 118 �˽� NULL 2017/8/25 15:30 119 ������ 90 120 СѾ NULL 2017/8/27 15:30 121 ���� 80 2017/8/28 15:30 122 ��߸ 75 123 ��«�� 70 2017/8/30 15:30 124 ���� NULL 2017/8/31 15:30 125 �繤 NULL 126 �嶠 NULL 2017/9/2 15:30 127 ˾�� 50 2017/9/3 15:30 128 ������ 58 2017/9/4 15:30 129 ���� 66 2017/9/5 15:30 Time taken: 0.134 seconds, Fetched: 18 row(s)
去所在目錄下轉碼,再Load
piconv -f gb2312 -t UTF-8 2.csv > 3.csv # 在hive中選擇正確的文件Load: hive> load data local inpath '/export/data/3.csv' into table students;
結果:
hive> select * from students; OK 112 小寶 35 2017/8/19 15:30 113 王明 45 114 魯班 55 2017/8/21 15:30 115 苗苗 NULL 116 少林寺 75 2017/8/23 15:30 117 體育界 85 2017/8/24 15:30 118 八戒 NULL 2017/8/25 15:30 119 周芷若 90 120 小丫 NULL 2017/8/27 15:30 121 海寶 80 2017/8/28 15:30 122 哪吒 75 123 葫蘆娃 70 2017/8/30 15:30 124 丹楓 NULL 2017/8/31 15:30 125 電工 NULL 126 村長 NULL 2017/9/2 15:30 127 司機 50 2017/9/3 15:30 128 王世間 58 2017/9/4 15:30 129 松鼠 66 2017/9/5 15:30 Time taken: 0.106 seconds, Fetched: 18 row(s)
補充:hive導入數據出現NULL
在把hdfs上數據遷移到hive中的表時,若出現數據位NULL,是因為沒有指定列分隔符。
由於hive默認的分隔符是/u0001(Ctrl+A),為瞭平滑遷移,需要在創建表格時指定數據的分割符號,語法如下:
hive (default)> create external table et (time BIGINT, userid string, content string, urlrank int, urlnum int, url string) > partitioned by (filenum int) > row format delimited fields terminated by '\t';
上面創建的是外部表,“導入”數據時可以用load,但若不想進行移動數據,就用命令alter來進行指向:
alter table et add partition (filenum=1) location '/input/SogouQueryLog/file1';
註意location後面跟的地址必須是個目錄,若不是,可以用hdfs fs -mv src dest 進行移動數據:
hadoop fs -mv /input/SogouQueryLog/querylog_1 /input/SogouQueryLog/file1
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- None Found