抽取數據到impala數據量異常

最近,用kettle把DB2的數據抽取到impala上,發現數據量異常,數據錯開等情況。

檢查發現DB2源表裏的數據某個字段中內容含有英文的逗號,而impala上建的表TERMINATED BY ','也用英文逗號分隔的,所以造成數據錯亂;另外源表數據字段內容包含換行、回車符也會導致到impala數據分隔異常 數據錯亂。
解決方案:針對分隔符,導致的 ;可以換一種分隔符 |,重新建表

CREATE TABLE DB_NAME.TB_NAME (
        ROW_ID DECIMAL(20,0),
        SLOGAN STRING,
        CREATED_TIME TIMESTAMP

)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
WITH SERDEPROPERTIES ('field.delim'='|', 'serialization.format'='|')
STORED AS TEXTFILE
LOCATION 'hdfs://IP:8020/user/hive/warehouse/XX.db/TB_NAME'

kettle 數據輸出組件上的分隔符也對應調整
在這裏插入圖片描述
或者不需要重建表,獲取數據時將字段中的英文逗號轉換成中文的replace(SLOGAN,',',',')
如果源數據中存在換行回車符,可以trim(replace(replace(SLOGAN ,CHAR(13),''),CHAR(10),' '))
如果都有直接都替換再傳到impala trim(replace(replace(replace(SLOGAN ,',',',') ,CHAR(13),''),CHAR(10),' '))

發現用kettle抽取DB2數據庫的數據到impala上的表(TEXTFILE格式存儲的表),源表中的字段例如ROW_ID是DECIMAL數值型的,impala上也是DECIMAL數值型的,如果不指定字段的長度和精度,hdfs文件裏有數據內容,但是impala表select時row_id顯示爲null;指定了BigNumber類型的長度和精度後(hdfs文件中該字段值不足20位會在前面用0補齊位數)則能select出來
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
例如源表字段CREATED_TIME是TIMESTAMP格式的, impala上對應字段也是TIMESTAMP的,hdfs文件裏的內容在時分秒後面有.000000000,則impala上查詢數據時顯示null;在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述
源表日期數據要格式化轉換下to_char(CREATED_TIME,'YYYY-MM-DD HH24:MI:SS') as CREATED_TIME再傳即可
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
所以 源表數據字段類型、長度等要匹配上Impala表的字段數據類型,否則select不出來,顯示null

備註:如果是mysql庫裏的TIMESTAMP的字段傳到impala上(impala對應字段類型也是TIMESTAMP),日期數據轉換下date_format(CREATED_TIME,'%Y-%m-%d %H:%i:%S') or date_format(CREATED_TIME,'%Y-%m-%d %T')

impala常用數據類型: 源自官方文檔

數據類型 詳細說明
BIGINT Range:-9223372036854775808 - 9223372036854775807 ;用於建表或者sql中:CREATE TABLE t1(x BIGINT);SELECT CAST(1000 AS BIGINT)
DOUBLE 存儲4.94065645841246544e-324d 至 1.79769313486231570e+308 範圍內的浮點值
DECIMAL 存儲十進制值 , Range:-10^38 +1 至 10^38 –1,最長的是DECIMAL(38, 0)
INT 存儲 -2147483648 至 2147483647範圍內的 4字節 整數
SMALLINT 存儲 -32768至32767範圍內的 2字節 整數
TINYINT 存儲 -128至127範圍內的 1字節 整數
FLOAT 存儲 1.40129846432481707e-45 至 3.40282346638528860e+38 範圍內的單精度浮點值
STRING 存儲 字符串值
VARCHAR 存儲可變長度字符,最大長度爲65535,VARCHAR(max_length)
CHAR 存儲固定長度字符,最大長度爲255,CHAR(length)
BOOLEAN 只存儲true或false值
TIMESTAMP 存儲時間格式的值,Range: 1400-01-01 to 9999-12-31,DATE_ADD (timestamp, INTERVAL interval time_unit)
ARRAY ARRAY < type >,存儲可變數量的有序元素,Complex Types (CDH 5.5 or higher only)
MAP MAP < primitive_type, type >,存儲可變數量的鍵值對,Complex Types (CDH 5.5 or higher only)
STRUCT STRUCT < name : type [COMMENT ‘comment_string’], … > ,表示單個項目的多個字段,Complex Types (CDH 5.5 or higher only)
REAL 是DOUBLE類型的一個別名,REAL and DOUBLE interchangeably(可交換的)

www:
有張表的記錄數據有創建時間和更新時間 TIMESTAMP格式,而且數據量較大;而記錄在創建以後可能N天之後會進行更新(大於1次),每天要從DB2數據庫更新數據到impala上;
創建TEXTFILE格式存儲數據的臨時表和PARQUET格式的正式表;每天根據臨時表的數據 overwrite 正式表 insert overwrite table XX.XXXX partition(dt_month_id,dt_day_id) select * from XX.XXXX_tmp;
一開始我根據創建時間或者更新時間的年月日創建分區,後面直接獲取最近幾天更新記錄數據,到最後 impala上總記錄數據總是或多(根據更新時間創建分區)或少(根據創建時間創建),因爲獲取的數據量肯定比實際分區文件中的文件或多或少。
最終的解決辦法是:截取創建時間的年月日創建分區cast(to_char(CREATED_TIME,'YYYYMMDD') as int) as dt_day_id,每天獲取最近幾天更新記錄的創建時間最小值,獲取大於等於最小創建時間的記錄數據 更新那些天的文件: where CREATED_TIME >= (select substr(min(CREATED_TIME),1,10) || ' 00:00:00' from XX.TB_NAME where to_char(LAST_UPD_TIME,'YYYYMMDD') >= to_char(current date - 2 day,'YYYYMMDD') )

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章