本文介紹CSV、TSV格式的OSS外部表格的建立、讀取及寫入方法。
前提條件
已具備訪問OSS的許可權。阿里雲帳號(主帳號)、RAM使用者或RAMRole身份可以訪問OSS外部表格,授權資訊請參見OSS的STS模式授權。
(可選)已準備好OSS儲存空間(Bucket)、OSS目錄及OSS資料檔案。具體操作請參見建立儲存空間、管理目錄和簡單上傳。
MaxCompute已支援在OSS側自動建立目錄,對於攜帶外部表格及UDF的SQL語句,您可以通過一條SQL語句執行讀寫外部表格及UDF的操作。原手動建立目錄方式仍然支援。
已建立MaxCompute專案。具體操作請參見建立MaxCompute專案。
由於MaxCompute只在部分地區部署,跨地區的資料連通性可能存在問題,因此建議Bucket與MaxCompute專案所在地區保持一致。
已具備在MaxCompute專案中建立表(CreateTable)的許可權。表操作的許可權資訊請參見MaxCompute許可權。
使用限制
OSS外部表格不支援cluster屬性。
單個檔案大小不能超過3 GB,如果檔案過大,建議拆分。
注意事項
若CSV/TSV檔案中的列數與外表DDL中的列數量的不一致,讀取CSV/TSV資料時會報錯“列數不匹配”,例如FAILED: ODPS-0123131:User defined function exception - Traceback:java.lang.RuntimeException: SCHEMA MISMATCH:xxx。
您可通過在Session層級設定odps.sql.text.schema.mismatch.mode參數,以控制輸出結果:
SET odps.sql.text.schema.mismatch.mode=error:表示列數不一致時,系統直接報錯。SET odps.sql.text.schema.mismatch.mode=truncate:表示列數不一致時,超過外表DDL中的列數部分將被丟棄;少於外表DDL中的列數部分,列值將被補充為NULL。
資料類型支援
更多有關SmartParse的說明,請參見Smart Parse更靈活的類型能力。
資料類型 | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (內建文本資料解析器) | org.apache.hadoop.hive.serde2.OpenCSVSerde (內建開來源資料解析器) |
TINYINT |
|
|
SMALLINT |
|
|
INT |
|
|
BIGINT |
|
|
BINARY |
|
|
FLOAT |
|
|
DOUBLE |
|
|
DECIMAL(precision,scale) |
|
|
VARCHAR(n) |
|
|
CHAR(n) |
|
|
STRING |
|
|
DATE |
|
|
DATETIME |
|
|
TIMESTAMP |
|
|
TIMESTAMP_NTZ |
|
|
BOOLEAN |
|
|
ARRAY |
|
|
MAP |
|
|
STRUCT |
|
|
JSON |
|
|
壓縮格式支援
當您需要讀寫壓縮屬性的OSS檔案時,需要在建表語句中添加with serdeproperties屬性配置,詳情請參見with serdeproperties屬性參數。
壓縮格式 | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (內建文本資料解析器) | org.apache.hadoop.hive.serde2.OpenCSVSerde (內建開來源資料解析器) |
GZIP |
|
|
SNAPPY |
|
|
LZO |
|
|
建立外部表格
文法結構
各格式的外部表格文法結構詳情,請參見OSS外部表格。
內建文本資料解析器
CSV格式
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <data_type>, ... ) [COMMENT <table_comment>] [PARTITIONED BY (<col_name> <data_type>, ...)] STORED BY 'com.aliyun.odps.CsvStorageHandler' [WITH serdeproperties ( ['<property_name>'='<property_value>',...] )] LOCATION '<oss_location>' [tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];TSV格式
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <data_type>, ... ) [COMMENT <table_comment>] [PARTITIONED BY (<col_name> <data_type>, ...)] STORED BY 'com.aliyun.odps.TsvStorageHandler' [WITH serdeproperties ( ['<property_name>'='<property_value>',...] )] LOCATION '<oss_location>' [tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];
內建開來源資料解析器
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <data_type>, ... ) [COMMENT <table_comment>] [PARTITIONED BY (<col_name> <data_type>, ...)] ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' [WITH serdeproperties ( ['<property_name>'='<property_value>',...] )] STORED AS TEXTFILE LOCATION '<oss_location>' [tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];
公用參數
公用參數說明請參見基礎文法參數說明。
專屬參數
with serdeproperties屬性參數
適用解析器 | property_name | 使用情境 | 說明 | property_value | 預設值 |
內建文本資料解析器(CsvStorageHandler/TsvStorageHandler) | odps.text.option.gzip.input.enabled | 當需要讀取以GZIP方式壓縮的CSV或TSV檔案資料時,請添加該屬性。 | CSV、TSV壓縮屬性。配置該參數值為True時,MaxCompute才可以正常讀取壓縮檔,否則會讀取失敗。 |
| False |
odps.text.option.gzip.output.enabled | 當需要將資料以GZIP壓縮方式寫入OSS時,請添加該屬性。 | CSV、TSV壓縮屬性。配置該參數值為True時,MaxCompute才能將資料以GZIP壓縮方式寫入OSS,否則不壓縮。 |
| False | |
odps.text.option.header.lines.count | 當OSS資料檔案為CSV或TSV,且需要忽略OSS資料檔案中的前N行時,請添加該屬性。 | MaxCompute讀取OSS資料檔案時,會忽略指定的行數。 | 非負整數 | 0 | |
odps.text.option.null.indicator | 當OSS資料檔案為CSV或TSV,且需要定義OSS資料檔案中NULL的解析規則時,請添加該屬性。 | 通過該參數配置的字串會被解析為SQL中的NULL。例如 | 字串 | Null 字元串 | |
odps.text.option.ignore.empty.lines | 當OSS資料檔案為CSV或TSV,且需要定義OSS資料檔案中空行的處理規則時,請添加該屬性。 | 配置該參數值為True時,MaxCompute會忽略資料檔案中的空行,否則會讀取空行。 |
| True | |
odps.text.option.encoding | 當OSS資料檔案為CSV或TSV,且OSS資料檔案編碼規則非預設編碼規則時,請添加該屬性。 | 確保此處配置的編碼規則與OSS資料檔案編碼規則保持一致,否則MaxCompute無法成功讀取資料。 |
| UTF-8 | |
odps.text.option.delimiter | 當需要明確CSV或TSV資料檔案的資料行分隔符號時,請添加該屬性。 | 確保此處配置的資料行分隔符號可以正確讀取OSS資料檔案的每一列,否則MaxCompute讀取的資料會出現錯位問題。 | 單個字元 | 半形逗號(,) | |
odps.text.option.use.quote | 當CSV或TSV資料檔案中的欄位包含換行(CRLF)、雙引號或英文逗號時,請添加該屬性。 | 當CSV某個欄位中包含換行、雙引號(需要在 |
| False | |
odps.sql.text.option.flush.header | 在往OSS寫資料的時候,檔案塊的第一行為表頭。 | 只有針對CSV檔案格式生效。 |
| False | |
odps.sql.text.schema.mismatch.mode | 當讀取的OSS檔案的資料列數和外部表格的Schema列數不一致時。 | 指定對於列數不一致行的處理方式。 說明:odps.text.option.use.quote參數值為True時,該功能不生效。 |
| error | |
內建開來源資料解析器(OpenCSVSerde) | separatorChar | 當需要明確以TEXTFILE格式儲存的CSV資料的資料行分隔符號時,請添加該屬性。 | 指定CSV資料資料行分隔符號。 | 單個字串 | 半形逗號(,) |
quoteChar | 當以TEXTFILE格式儲存的CSV資料中的欄位包含換行、雙引號或英文逗號時,請添加該屬性。 | 指定CSV資料的引用符。 | 單個字串 | 無 | |
escapeChar | 當需要明確以TEXTFILE格式儲存的CSV資料的轉義規則時,請添加該屬性。 | 指定CSV資料的轉義符。 | 單個字串 | 無 |
tblproperties屬性參數
適用解析器 | property_name | 使用情境 | 說明 | property_value | 預設值 |
內建開來源資料解析器(OpenCSVSerde) | skip.header.line.count | 當需要忽略以TEXTFILE格式儲存的CSV檔案中的前N行資料時,請添加該屬性。 | MaxCompute讀取OSS資料時,會忽略從首行開始指定行數的資料。 | 非負整數 | 無 |
skip.footer.line.count | 當需要忽略以TEXTFILE格式儲存的CSV檔案中的後N行資料時,請添加該屬性。 | MaxCompute讀取OSS資料時,會忽略從尾行開始指定行數的資料。 | 非負整數 | 無 | |
mcfed.mapreduce.output.fileoutputformat.compress | 當需要將TEXTFILE資料檔案以壓縮方式寫入OSS時,請添加該屬性。 | TEXTFILE壓縮屬性。配置該參數值為True時,MaxCompute才可以將TEXTFILE資料檔案以壓縮方式寫入OSS,否則不壓縮。 |
| False | |
mcfed.mapreduce.output.fileoutputformat.compress.codec | 當需要將TEXTFILE資料檔案以壓縮方式寫入OSS時,請添加該屬性。 | TEXTFILE壓縮屬性。設定TEXTFILE資料檔案的壓縮方式。 說明:只支援 |
| 無 | |
io.compression.codecs | 當OSS資料檔案為Raw-Snappy格式時,請添加該屬性。 | 配置該參數值為True時,MaxCompute才可以正常讀取壓縮資料,否則MaxCompute無法成功讀取資料。 | com.aliyun.odps.io.compress.SnappyRawCodec | 無 |
寫入資料
MaxCompute寫入文法詳情,請參見寫入文法說明。
查詢分析
Smart Parse更靈活的類型能力
針對CSV格式的OSS外部表格,MaxCompute SQL採用2.0資料類型進行讀寫,之前僅支援部分嚴格格式的值,並按照相應的資料類型進行讀寫。現已相容讀取CSV中各種類型的值。具體如下:
Type | Input as String | Output as String | Description |
BOOLEAN |
說明 解析時會對輸入執行 |
| 不在枚舉值範圍,則解析失敗。 |
TINYINT |
說明
|
| 8位整型,超出範圍範圍 |
SMALLINT | 16位整型,超出範圍範圍 | ||
INT | 32位整型,超出範圍範圍 | ||
BIGINT | 64位整型,超出範圍範圍 說明
| ||
FLOAT |
說明
|
| 特殊值(大小寫不敏感)包括:NaN、Inf、-Inf、Intifniy和-Intifniy。在超出範圍範圍時,將報錯;若精度超出,則進行四捨五入截斷。 |
DOUBLE |
說明
|
| 特殊值(大小寫不敏感)包括:NaN、Inf、-Inf、Intifniy和-Intifniy。在超出範圍範圍時,將報錯;若精度超出,則進行四捨五入截斷。 |
DECIMAL (precision, scale) 以DECIMAL(15,2)為例 |
說明
|
| 整數部分值超出 則會報錯;小數部分超出scale,則會進行四捨五入截斷。 |
CHAR(n) 以CHAR(7)為例 |
|
| 最大長度為255。長度不足則會填充空格,但空格不參與比較。長度超出n會截斷。 |
VARCHAR(n) 以VARCHAR(7)為例 |
|
| 最大長度為65535。長度超出n會截斷。 |
STRING |
|
| 長度限制為8 MB。 |
DATE |
說明 您也可以通過自訂 |
|
|
TIMESTAMP_NTZ 說明 OpenCsvSerde不支援此類型,因為該類型與Hive資料格式不相容。 |
|
|
|
DATETIME |
| 假設系統時區為Asia/Shanghai:
|
|
TIMESTAMP |
| (假設系統時區為Asia/Shanghai)
|
|
注意事項
對於任意類型,CSV資料檔案中的Null 字元串被讀入表中後,均會被解析為NULL。
不支援STRUCT/ARRAY/MAP等複雜類型,因為這些複雜類型的值很容易和CSV的常見分隔字元(,)發生衝突導致解析失敗。
暫不支援BINARY/INTERVAL類型,如有需求請聯絡MaxCompute支援人員。
對於資料類型INT/SMALLINT/TINYINT/BIGINT/FLOAT/DOUBLE/DECIMAL,預設的解析能力(DEFAULT)比較豐富。
如果您只想對基礎的數字串進行解析,可以在
tblproperties中將odps.text.option.smart.parse.level參數設定為naive,使解析器僅支援解析普通數字串,例如“123”、“123.456”,其他形態的字串在解析時會報錯。對於四種日期或時間相互關聯類型DATA/DATATIME/TIMESTAMP/TIMESTAMP_NTZ,在底層代碼中均使用
java.time.format.DateTimeFormatter進行處理。MaxCompute內建了若干的預設解析格式,您也可以通過在tblproperties中設定odps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.format來自訂多種解析格式與一種輸出格式,解析格式之間用#分隔。自訂格式的優先順序高於MaxCompute的內建解析格式,輸出格式將採用第一個自訂格式。
例如,若您自訂DATE類型的格式串為
pattern1#pattern2#pattern3,則可以解析符合pattern1、pattern2或pattern3的字串,但輸出至檔案時會採用pattern1格式來輸出。詳情請參見DateTimeFormatter。不建議使用 'z' (time-zone name) 作為自訂的時區格式(尤其對於中國區使用者),因為 'z' 在某些上下文中可能存在歧義。
例如:'CST' 在中國語境下通常表示中國標準時間(UTC+8),然而當 'CST' 被
java.time.format.DateTimeFormatter解析時,會被識別為美國中部標準時間(UTC-6),這可能導致非預期的輸入或輸出結果。建議您改用 'x' (zone-offset) 或 'VV' (time-zone ID) 作為時區模式。
使用樣本
執行下述範例程式碼時,請將代碼中的
<uid>替換為您的阿里雲帳號ID。下述樣本中使用的角色為
aliyunodpsdefaultrole,如果您想使用其他角色,需要將aliyunodpsdefaultrole替換為目標角色名稱,並為目標角色授予訪問OSS的許可權。
通過內建文本資料解析器建立OSS外部表格
樣本一:非分區表
與樣本資料中的
Demo1/目錄建立映射關係。建立OSS外部表格的命令樣本如下。CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external1 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo1/'; -- 您可以執行desc extended mc_oss_csv_external1;命令查看建立好的OSS外部表格結構資訊。查詢非分區外表。
SELECT * FROM mc_oss_csv_external1;返回結果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 1 | 51 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | W | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 6 | 9 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | S | | 1 | 7 | 53 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | | 1 | 8 | 63 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | SW | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | | 1 | 10 | 31 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | +------------+------------+------------+------------+------------------+-------------------+------------+----------------+寫入資料至非分區外表,並查看資料是否已成功寫入。
INSERT INTO mc_oss_csv_external1 VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10','SW'); SELECT * FROM mc_oss_csv_external1 WHERE recordId=12;返回結果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+查看OSS路徑
Demo1/下已產生新檔案。
樣本二:分區表
與樣本資料中的
Demo2/目錄建立映射關係。建立OSS外部表格並引入分區資料的命令樣本如下。CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external2 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING ) PARTITIONED BY ( direction STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo2/'; -- 您可以執行DESC EXTENDED mc_oss_csv_external2;命令查看建立好的外部表格結構資訊。引入分區資料。當建立的OSS外部表格為分區表時,需要額外執行引入分區資料的操作,更多操作請參見補全OSS外部表格分區資料文法。
MSCK REPAIR TABLE mc_oss_csv_external2 ADD PARTITIONS; --等效於如下語句。 ALTER TABLE mc_oss_csv_external2 ADD PARTITION (direction = 'N') PARTITION (direction = 'NE') PARTITION (direction = 'S') PARTITION (direction = 'SW') PARTITION (direction = 'W');查詢分區外表。
SELECT * FROM mc_oss_csv_external2 WHERE direction='NE';返回結果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+寫入資料至分區外表,並查看是否已成功寫入。
INSERT INTO mc_oss_csv_external2 PARTITION(direction='NE') VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10'); SELECT * FROM mc_oss_csv_external2 WHERE direction='NE' AND recordId=12;返回結果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+查看OSS路徑
Demo2/direction=NE下已產生新檔案。
樣本三:壓縮資料
本樣本建立以GZIP壓縮的CSV格式外表,進行資料讀取和寫入操作。
建立內部表並寫入測試資料,用來進行後續的寫入測試。
CREATE TABLE vehicle_test( vehicleid INT, recordid INT, patientid INT, calls INT, locationlatitute DOUBLE, locationlongtitue DOUBLE, recordtime STRING, direction STRING ); INSERT INTO vehicle_test VALUES (1,1,51,1,46.81006,-92.08174,'9/14/2014 0:00','S');建立以GZIP壓縮的CSV格式外表,與樣本資料中的
Demo3/(壓縮資料)目錄建立映射關係。建立OSS外部表格命令樣本如下。CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external3 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) PARTITIONED BY (dt STRING) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole', 'odps.text.option.gzip.input.enabled'='true', 'odps.text.option.gzip.output.enabled'='true' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo3/'; -- 引入分區資料 MSCK REPAIR TABLE mc_oss_csv_external3 ADD PARTITIONS; -- 您可以執行DESC EXTENDED mc_oss_csv_external3;命令查看建立好的外部表格結構資訊。使用MaxCompute用戶端,從OSS中讀取資料。命令樣本如下:
說明如果OSS壓縮資料為開來源資料格式,需要在SQL語句前添加
set odps.sql.hive.compatible=true;命令,與SQL語句一起提交執行。--開啟全表掃描,僅此Session有效。 SET odps.sql.allow.fullscan=true; SELECT recordId, patientId, direction FROM mc_oss_csv_external3 WHERE patientId > 25;返回結果如下:
+------------+------------+------------+ | recordid | patientid | direction | +------------+------------+------------+ | 1 | 51 | S | | 3 | 48 | NE | | 4 | 30 | W | | 5 | 47 | S | | 7 | 53 | N | | 8 | 63 | SW | | 10 | 31 | N | +------------+------------+------------+讀取內部表的資料寫入至OSS外表。
通過MaxCompute用戶端對外部表格執行
INSERT OVERWRITE或INSERT INTO命令,將資料寫入OSS。INSERT INTO TABLE mc_oss_csv_external3 PARTITION (dt='20250418') SELECT * FROM vehicle_test;執行成功後,您可在OSS目錄下查看匯出的檔案。
建立OSS外部表格並指定對應OSS檔案的第一行為表頭
在樣本資料的oss-mc-testBucket下建立Demo11目錄,並執行如下語句:
--建立外部表格
CREATE EXTERNAL TABLE mf_oss_wtt
(
id BIGINT,
name STRING,
tran_amt DOUBLE
)
STORED BY 'com.aliyun.odps.CsvStorageHandler'
WITH serdeproperties (
'odps.text.option.header.lines.count' = '1',
'odps.sql.text.option.flush.header' = 'true'
)
LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo11/';
--插入資料
INSERT OVERWRITE TABLE mf_oss_wtt VALUES (1, 'val1', 1.1),(2, 'value2', 1.3);
--查詢資料
--在建表的時候可以把所有欄位建成string,否則表頭讀取時會報錯。
--或者在建表的時候需要加跳過表頭的參數:'odps.text.option.header.lines.count' = '1'
SELECT * FROM mf_oss_wtt;返回結果如下:
+----------+--------+------------+
| id | name | tran_amt |
+----------+--------+------------+
| 1 | val1 | 1.1 |
| 2 | value2 | 1.3 |
+----------+--------+------------+建立OSS外部表格且外部表格列數與OSS資料列數不一致
在樣本資料的
oss-mc-testBucket下建立demo目錄,並上傳test.csv檔案。test.csv檔案內容如下。1,kyle1,this is desc1 2,kyle2,this is desc2,this is two 3,kyle3,this is desc3,this is three, I have 4 columns建立外部表格。
指定對於列數不一致的行的處理方式為
TRUNCATE。--刪除表 DROP TABLE test_mismatch; --建立外部表格 CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch ( id string, name string, dect string, col4 string ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ('odps.sql.text.schema.mismatch.mode' = 'truncate') LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/';指定對於列數不一致的行的處理方式為
IGNORE。--刪除表 DROP TABLE test_mismatch01; --建立外部表格 CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch01 ( id STRING, name STRING, dect STRING, col4 STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ('odps.sql.text.schema.mismatch.mode' = 'ignore') LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/';查詢表資料。
查詢test_mismatch表。
SELECT * FROM test_mismatch; --返回結果 +----+-------+---------------+---------------+ | id | name | dect | col4 | +----+-------+---------------+---------------+ | 1 | kyle1 | this is desc1 | NULL | | 2 | kyle2 | this is desc2 | this is two | | 3 | kyle3 | this is desc3 | this is three | +----+-------+---------------+---------------+查詢test_mismatch01表。
SELECT * FROM test_mismatch01; --返回結果 +----+-------+----------------+-------------+ | id | name | dect | col4 | +----+-------+----------------+-------------+ | 2 | kyle2 | this is desc2 | this is two +----+-------+----------------+-------------+
通過內建開源解析器建立OSS外部表格
通過內建開源解析器建立OSS外部表格讀取以逗號為分隔字元的檔案,並忽略首行和尾行的資料。
在樣本資料的
oss-mc-testBucket下建立demo-test目錄,並上傳測試檔案test.csv。測試檔案包含的資料資訊如下。
1,1,51,1,46.81006,-92.08174,9/14/2014 0:00,S 1,2,13,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,3,48,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,4,30,1,46.81006,-92.08174,9/14/2014 0:00,W 1,5,47,1,46.81006,-92.08174,9/14/2014 0:00,S 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00,S 1,7,53,1,46.81006,-92.08174,9/15/2014 0:00,N 1,8,63,1,46.81006,-92.08174,9/15/2014 0:00,SW 1,9,4,1,46.81006,-92.08174,9/15/2014 0:00,NE 1,10,31,1,46.81006,-92.08174,9/15/2014 0:00,N建立外部表格,並指定分隔字元為逗號,設定忽略首行和尾行參數。
CREATE EXTERNAL TABLE ext_csv_test08 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT serde 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH serdeproperties ( "separatorChar" = "," ) stored AS textfile location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/***/' -- 設定忽略首行和尾行參數。 TBLPROPERTIES ( "skip.header.line.COUNT"="1", "skip.footer.line.COUNT"="1" ) ;讀取外部表格。
SELECT * FROM ext_csv_test08; -- 返回結果,唯讀了8條,忽略了首行和尾行。 +------------+------------+------------+------------+------------------+-------------------+------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+------------+------------+ | 1 | 1 | 51 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | W | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 6 | 9 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | S | | 1 | 7 | 53 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | | 1 | 8 | 63 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | SW | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | | 1 | 10 | 31 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | +------------+------------+------------+------------+------------------+-------------------+------------+------------+
建立CSV格式的OSS外部表格-自訂各種時間資料類型
CSV自訂時間類型的解析與輸出格式詳情,請參見Smart Parse更靈活的類型能力。
建立各時間資料類型的CSV外表(datetime/timestamp/timestamp_ntz)。
CREATE EXTERNAL TABLE test_csv ( col_date DATE, col_datetime DATETIME, col_timestamp TIMESTAMP, col_timestamp_ntz TIMESTAMP_NTZ ) STORED BY 'com.aliyun.odps.CsvStorageHandler' LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/' TBLPROPERTIES ( 'odps.text.option.date.io.format' = 'MM/dd/yyyy', 'odps.text.option.datetime.io.format' = 'yyyy-MM-dd-HH-mm-ss x', 'odps.text.option.timestamp.io.format' = 'yyyy-MM-dd HH-mm-ss VV', 'odps.text.option.timestamp_ntz.io.format' = 'yyyy-MM-dd HH:mm:ss.SS' ); INSERT OVERWRITE test_csv VALUES(DATE'2025-02-21', DATETIME'2025-02-21 08:30:00', TIMESTAMP'2025-02-21 12:30:00', TIMESTAMP_NTZ'2025-02-21 16:30:00.123456789');插入資料後,CSV檔案的內容為:
02/21/2025,2025-02-21-08-30-00 +08,2025-02-21 12-30-00 Asia/Shanghai,2025-02-21 16:30:00.12再次讀資料,可以看到結果。
SELECT * FROM test_csv;返回結果如下:
+------------+---------------------+---------------------+------------------------+ | col_date | col_datetime | col_timestamp | col_timestamp_ntz | +------------+---------------------+---------------------+------------------------+ | 2025-02-21 | 2025-02-21 08:30:00 | 2025-02-21 12:30:00 | 2025-02-21 16:30:00.12 | +------------+---------------------+---------------------+------------------------+