准備工作:
1.因為gpload是對gpfdist的封裝,因此使用gpload之前必須開啟gpfdist的服務,不然無法使用。
gpfdist -d /home/admin -p 8181 -l /tmp/gpfdist.log &
開啟服務的命令這里就不詳解,可以參考我之前講解的gpfdist文檔: http://www.cnblogs.com/daojiao/p/4589038.html
2.系統需要安Python工具,因為我用的是紅帽子系統(redhat),內置了此工具,因此不需要安裝。
3.首先准備數據文件(這里就補貼數據文件了,直接打印出文件名及文件中的書):
4.GP庫中創建裝載數據的表:
create table member_delta ( mever_id varchar(54) ,phoneno varchar(20) ,action char(1) ,dw_ins_date date ) with ( appendonly=true ,compresslevel=5 ) distributed by (mever_id) partition by list (action) ( partition u values('U'), partition i values('I'), partition d values('D'), default partition other_action ) ;
表結構大概講解下: 這張表附加了分布鍵,數據壓縮,數據分區等功能。
開始gpload的編碼:
創建執行的腳本(這里的腳本就是上面所提到的Python語言),文件名為member.yml:
VERSION: 1.0.0.1 DATABASE: Test USER: gpadmin HOST: 192.168.23.128 PORT: 5432 GPLOAD: INPUT: - SOURCE: LOCAL_HOSTNAME: - mdw PORT: 8181 FILE: - /home/admin/member_delta.txt - COLUMNS: - mever_id: varchar(54) - phoneno: varchar(20) - action: char(1) - dw_ins_date: date - FORMAT: text - DELIMITER: ' ' - QUOTE: '"' - HEADER: true - ERROR_LIMIT: 25 - ERROR_TABLE: public.member_err OUTPUT: - TABLE: public.member_delta - MODE: INSERT
腳本所用參數的含義
VERSION: 1.0.0.1 --指定控制文件schema的版本 DATABASE: db_name --指定連接數據庫的名字,如果沒有指定,由環境變量$PGDATABASE,或者通過gpload參數-d指定 USER: db_username --指定連接目標數據庫的用戶名,如果不使用超級管理員,服務參數gp_external_grant_privileges必須設置成on。 HOST: master_hostname --指定master主機名,也可以通過gpload的-h選項,或者環境變量$PGHOST指定 PORT: master_port --指定master的連接端口號,默認是5432,或者通過gpload命令的-p選項或者環境變量$PGPORT指定。 GPLOAD: --必須指定,表示裝載設置部分在它下面必須定義INPUT:和OUTPUT:兩個部分。 INPUT: --必須指定,這部分指定裝載數據的格式和位置 - SOURCE: --必須指定,定義source文件的位置,每個輸入部分可以定義多個source部分, windows路徑的指定比較特別,比如c:\ 要寫成 c:/ LOCAL_HOSTNAME: --指定gpload運行的主機名稱和ip地址,如果有多塊網卡,可以同時使用它們,提高裝載速度。默認只使用首選主機名和IP。 - hostname_or_ip PORT: http_port --指定gpfdist使用的端口,也可以選擇端口范圍,由系統選擇,如果同時指定,port設置優先級高。 | PORT_RANGE: [start_port_range, end_port_range] FILE: --指定裝載數據文件的位置,目錄或者命名管道。如果文件使用gpzip或者bzip2進行了壓縮,它可以自動解壓。可以使用通配符*和C語言風格的關系匹配模式指定多個文件。 - /path/to/input_file - COLUMNS: --指定數據源的數據格式,如果沒有指定這部分,source表的列順序,數量,以及數據類型必須與目標表一致。 - field_name: data_type - FORMAT: text | csv --指定文件格式是text還是csv - DELIMITER: 'delimiter_character' --指定文本數據域(列)之間的分割符,默認是| - ESCAPE: 'escape_character' | 'OFF' --text定義轉義字符,text格式默認是\,在text格式中可以選擇off關掉轉義字符(web log處理時比較有用) - NULL_AS: 'null_string' --指定描述空值的字符串,text格式默認是\N,csv格式不使用轉義符號的空值。 - FORCE_NOT_NULL: true | false --csv格式,強制所有字符默認都用”“括起,因此不能有空值,如果兩個分割符之間沒有值,被當做0長度字符串,認為值已經丟失。 - QUOTE: 'csv_quote_character' --csv指定轉義字符,默認是" - HEADER: true | false --是否跳過數據文件第一行,當做表頭 - ENCODING: database_encoding --指定數據源的字符集 - ERROR_LIMIT: integer --指定由於不符合格式數據記錄的上限,如果超過該上限,gpload停止裝載,否則正確記錄可以被裝載,錯誤記錄拋出寫入錯誤表。但它僅支持數據格式錯誤,不支持違背約束的問題 - ERROR_TABLE: schema.table_name --指定不符合格式要求記錄的錯誤表。如果指定的表不存在系統自動創建。 OUTPUT: - TABLE: schema.table_name --指定裝載的目標表 - MODE: insert | update | merge --指定操作模式,默認是insert。merge操作不支持使用隨機分布策略的表。 - MATCH_COLUMNS: --為update操作和merge操作指定匹配條件。 - target_column_name - UPDATE_COLUMNS: --為update操作和merge操作指定更新的列 - target_column_name - UPDATE_CONDITION: 'boolean_condition' --指定where條件,目標表中只有滿足條件的記錄才能更改,(merge情況下,只有滿足條件的記錄才能insert) - MAPPING: --指定source列和目標列的映射關系。 target_column_name: source_column_name | 'expression' PRELOAD: --指定load之前的操作 - TRUNCATE: true | false --如果設置成true,裝載之前先刪除目標表中所有記錄,再裝載 - REUSE_TABLES: true | false --設置成true,不會刪除外部表對象會這中間表對象。從而提升性能。 SQL: - BEFORE: "sql_command" --裝載操作開始前執行的SQL,比如寫日志表 - AFTER: "sql_command" --裝載操作之后執行的SQL。
執行腳本:
腳本完成后,放在指定服務器位置,比如/home/command/ 目錄下
進入服務器找到存放腳本的目錄: cd /home/command/ 執行該腳本
執行命令為:gpload -f member.yml 腳本執行完后,打印台會得到如下信息:
查詢member_delta,看數據是否添加成功:
select * from member_delta;
總結:
今天寫這個例子,雖然是一個簡單的例子,但大概讓我知道gpload執行的流程是什么。寫這個腳本也折騰了不少時間,關鍵沒人教你,從頭到尾都是自己在摸索,不懂baidu,不懂翻書,一句話為了寫出這個程序不擇手段的進行各種嘗試,其中的抓狂無奈……但和結果比起來卻現的那么微不足道,寫飄了,進入正題,今天遇到一個蛋疼的問題就是不夠認真,腳本中的個別關鍵字寫錯了,確實比較捉急,還有就是剛開始沒找到正規的文檔,隨手捏來一個例子,不知道意思改了半天,這樣做真的很浪費時間,對於這個處理個人感覺盡量找官方文檔,查看具體每個參數的含義,那些可以寫,那些可以省掉。在開始寫的時候保證基本語法通過就OK了,不要寫太多無用的參數。