Object Storage Service (OSS) に保存されている CSV および TSV データの外部テーブルを作成、読み取り、書き込みする方法について説明します。
注意事項
OSS 外部テーブルはクラスタープロパティをサポートしていません。
単一ファイルのサイズは 2 GB を超えることはできません。2 GB を超えるファイルは分割する必要があります。
MaxCompute と OSS は同じリージョンにある必要があります。
サポートされるデータ型
MaxCompute のデータ型の詳細については、「データ型バージョン 1.0」および「データ型バージョン 2.0」をご参照ください。
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 ファイルの読み取りまたは書き込みを行う場合、`CREATE TABLE` ステートメントに with serdeproperties 属性を含める必要があります。詳細については、「with serdeproperties 属性パラメーター」をご参照ください。
圧縮形式 | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (組み込み) | org.apache.hadoop.hive.serde2.OpenCSVSerde (オープンソース) |
GZIP | ||
SNAPPY | ||
LZO | ||
ZSTD |
サポートされるスキーマ進化
操作 | サポート対象 | 説明 |
列の追加 |
| |
列の削除 | この操作はスキーマとデータの不一致を引き起こす可能性があるため、推奨されません。 | |
列の順序変更 | この操作はスキーマとデータの不一致を引き起こす可能性があるため、推奨されません。 | |
列のデータ型変更 | サポートされているデータ型変換のリストについては、「列のデータ型変更」をご参照ください。 | |
列名の変更 | ||
列コメントの変更 | コメントは、最大長 1,024 バイトの有効な文字列である必要があります。そうでない場合、エラーが発生します。 | |
列の Null 許容属性の変更 | この操作はサポートされていません。列はデフォルトで Null 許容です。 |
パラメーター設定
CSV または TSV 外部テーブルのスキーマは、位置によってファイル列にマッピングされます。OSS ファイルの列数が外部テーブルのスキーマの列数と一致しない場合、odps.sql.text.schema.mismatch.mode パラメーターを使用して、不一致な行の処理方法を指定できます。
odps.sql.text.schema.mismatch.modeが truncate に設定されている場合、列の変更は次の効果をもたらします:新しいスキーマに準拠するデータは期待通りに読み取られます。
古いスキーマを使用する既存データは、新しいスキーマに基づいて読み取られます。
たとえば、テーブルに列を追加した場合、テーブルを読み取るとその列の既存データは NULL として表示されます。
odps.sql.text.schema.mismatch.modeが ignore に設定されている場合、列の変更は次の効果をもたらします:新しいスキーマに準拠するデータは期待通りに読み取られます。
古いスキーマを使用する既存データは、新しいスキーマに基づいて読み取られます。
たとえば、テーブルに列を追加した場合、テーブルを読み取ると新しい列がない既存データの行全体が破棄されます。
odps.sql.text.schema.mismatch.modeが error に設定されている場合、列の変更は次の効果をもたらします:新しいスキーマに準拠するデータは期待通りに読み取られます。
古いスキーマを使用する既存データは、新しいスキーマに基づいて読み取られます。
たとえば、テーブルに列を追加した場合、新しい列がない既存データを読み取ろうとするとエラーが発生します。
外部テーブルの作成
構文
組み込みテキストパーサー
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 パラメーター
適用可能なパーサー | パラメーター | ユースケース | 説明 | 値 | デフォルト |
組み込みテキストデータパーサー (CsvStorageHandler/TsvStorageHandler) | odps.text.option.gzip.input.enabled | このプロパティを使用して、GZIP 形式で圧縮された CSV または TSV ファイルを読み取ります。 | CSV および TSV 圧縮プロパティ。このプロパティを |
| False |
odps.text.option.gzip.output.enabled | このプロパティを使用して、データを GZIP 圧縮形式で OSS に書き込みます。 | CSV および TSV 圧縮プロパティ。このプロパティを |
| False | |
odps.text.option.header.lines.count | このプロパティを使用して、OSS 内の CSV または TSV ファイルの最初の N 行をスキップします。 | データの読み取り時にファイルの先頭からスキップするヘッダー行の数を指定します。 | 非負整数 | 0 | |
odps.text.option.null.indicator | このプロパティを使用して、データ内の NULL 値を表すカスタム文字列を定義します。 | MaxCompute は指定された文字列を たとえば、ファイル内の | 文字列 | 空の文字列 | |
odps.text.option.ignore.empty.lines | このプロパティを使用して、CSV または TSV ファイル内の空の行の処理方法を定義します。 |
|
| True | |
odps.text.option.encoding | データファイルがデフォルトの UTF-8 エンコーディングを使用していない場合、このプロパティを使用します。 | ここで指定されたエンコーディングは、ファイルの実際のエンコーディングと一致する必要があります。不一致は読み取りの失敗を引き起こします。 |
| UTF-8 | |
odps.text.option.delimiter | このプロパティを使用して、CSV または TSV ファイルの列区切り文字を指定します。 | データの不整合を防ぐために、指定された区切り文字がデータファイル内の列を正しく分離していることを確認してください。 | 単一文字 | コンマ (,) | |
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 | データファイル内の行の列数が外部テーブルのスキーマと異なる場合、このプロパティを使用します。 | テーブルスキーマと列数が一致しない行の処理方法を指定します。 注: この機能は |
| error | |
odps.text.option.zstd.input.enabled | このプロパティを使用して、ZSTD 形式で圧縮された CSV または TSV ファイルを読み取ります。 | CSV および TSV 圧縮プロパティ。このプロパティを True に設定すると、MaxCompute は ZSTD 圧縮ファイルを読み取ります。それ以外の場合、読み取り操作は失敗します。 |
| False | |
odps.text.option.zstd.output.enabled | このプロパティを使用して、データを ZSTD 圧縮形式で OSS に書き込みます。 | CSV および TSV 圧縮プロパティ。このプロパティを True に設定すると、OSS への書き込み時にデータが ZSTD 形式で圧縮されます。それ以外の場合、データは非圧縮で書き込まれます。 |
| False | |
組み込みオープンソースデータパーサー (OpenCSVSerde) | separatorChar | このプロパティを使用して、TEXTFILE として保存された CSV データの列区切り文字を指定します。 | 列区切り文字を指定します。 | 単一文字 | コンマ (,) |
quoteChar | CSV データのフィールドに区切り文字や改行などの特殊文字が含まれている場合、このプロパティを使用します。 | フィールドを引用符で囲むために使用される文字を指定します。 | 単一文字 | なし | |
escapeChar | このプロパティを使用して、TEXTFILE として保存された CSV データのエスケープ文字を指定します。 | フィールド内の特殊文字をエスケープするために使用される文字を指定します。 | 単一文字 | なし |
tblproperties パラメーター
適用可能なパーサー | パラメーター | ユースケース | 説明 | 値 | デフォルト |
組み込みオープンソースデータパーサー (OpenCSVSerde) | skip.header.line.count | このプロパティを使用して、TEXTFILE として保存された CSV ファイルの最初の N 行をスキップします。 | データの読み取り時にファイルの先頭からスキップするヘッダー行の数を指定します。 | 非負整数 | なし |
skip.footer.line.count | このプロパティを使用して、TEXTFILE として保存された CSV ファイルの最後の N 行をスキップします。 | データの読み取り時にファイルの末尾からスキップするフッター行の数を指定します。 | 非負整数 | なし | |
mcfed.mapreduce.output.fileoutputformat.compress | このプロパティを使用して、TEXTFILE データを圧縮して OSS に書き込みます。 | TEXTFILE 圧縮プロパティ。 |
| False | |
mcfed.mapreduce.output.fileoutputformat.compress.codec | このプロパティを使用して、圧縮された TEXTFILE データを OSS に書き込む際の圧縮コーデックを指定します。 | TEXTFILE 圧縮プロパティ。TEXTFILE 出力の圧縮コーデックを指定します。 注: MaxCompute は |
| なし | |
io.compression.codecs | OSS データファイルが Raw-Snappy 形式で圧縮されている場合、このプロパティを使用します。 | MaxCompute が Raw-Snappy 圧縮データを読み取れるようにします。この設定がない場合、読み取り操作は失敗します。 | com.aliyun.odps.io.compress.SnappyRawCodec | なし | |
odps.text.option.bad.row.skipping | このプロパティを使用して、OSS に保存されている CSV ファイル内のダーティデータをスキップします。 | MaxCompute がダーティデータと見なされる行をスキップするか、エラーを報告するかを制御します。 |
| なし |
データの書き込み
MaxCompute の書き込み構文の詳細については、「書き込み構文」をご参照ください。
クエリと分析
SELECT 構文の詳細については、「クエリ構文」をご参照ください。
クエリプランの最適化の詳細については、「クエリの最適化」をご参照ください。
詳細については、「BadRowSkipping」をご参照ください。
BadRowSkipping
BadRowSkipping 機能を使用すると、クエリの失敗を引き起こす可能性のある CSV データ内の不正な行をスキップできます。この設定はエラー処理を制御し、基になるデータ形式の解析方法には影響しません。
パラメーター
テーブルレベルのパラメーター:
odps.text.option.bad.row.skippingrigid:スキップを強制します。この設定は、セッションレベルまたはプロジェクトレベルの構成で上書きすることはできません。flexible:スキップを有効にします。この設定は柔軟であり、セッションレベルまたはプロジェクトレベルの構成で上書きできます。
session/projectレベルのパラメーターodps.sql.unstructured.text.bad.row.skippingパラメーターは、flexibleなテーブルレベルのパラメーターを上書きできますが、rigidなものは上書きできません。on:機能を有効にします。テーブルに機能が設定されていない場合、デフォルトで有効になります。off:機能を無効にします。テーブルが flexible に設定されている場合、機能は無効になります。それ以外の場合、テーブルパラメーターの設定が使用されます。<null> または無効な入力:テーブルレベルの構成が使用されます。
odps.sql.unstructured.text.bad.row.skipping.debug.num:Logview の標準出力に出力するエラー結果の数を指定します。最大値は 1000 です。
値が <=0 の場合、この機能は無効になります。
値が無効な場合、この機能は無効になります。
セッションレベルのパラメーターとテーブルプロパティの相互作用
テーブルプロパティ
セッションフラグ
結果
rigid
on
On、強制的に On
off
<null>、無効な値、またはパラメーターが設定されていない
flexible
on
On
off
Off、セッションによって無効化
<null>、無効な値、またはパラメーターが設定されていない
On
未設定
on
On、セッションによって有効化
off
Off
<null>、無効な値、またはパラメーターが設定されていない
例
データの準備
不正な行を含むテストデータファイル csv_bad_row_skipping.csv を OSS のディレクトリ、たとえば
oss-mc-test/badrow/にアップロードします。CSV 外部テーブルの作成
以下の例は、テーブルレベルとセッションレベルのパラメーターの異なる組み合わせに基づく 3 つのシナリオを示しています。
テーブルパラメーター:
odps.text.option.bad.row.skipping = flexible | rigid | <not set>セッションフラグ:
odps.sql.unstructured.text.bad.row.skipping = on | off | <not set>
パラメーター未設定
-- テーブルレベルのパラメーターは設定されていません。セッションレベルのフラグで上書きされない限り、不正な行でクエリは失敗します。 CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flag ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>';柔軟なスキップ
-- テーブルは不正な行をスキップするように設定されていますが、これはセッションレベルのフラグで無効にできます。 CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flexible ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>' tblproperties ( 'odps.text.option.bad.row.skipping' = 'flexible' -- 柔軟なスキップを有効にします。これはセッションレベルで無効にできます。 );固定的なスキップ
-- テーブルは不正な行を強制的にスキップするように設定されています。これはセッションレベルで無効にすることはできません。 CREATE EXTERNAL TABLE test_csv_bad_data_skipping_rigid ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>' tblproperties ( 'odps.text.option.bad.row.skipping' = 'rigid' -- スキップを強制的にオンにします。 );クエリ結果の検証
パラメーター未設定
-- 次のコマンドはスキップを有効にしますが、この例の次のコマンドによってすぐに上書きされます。 SET odps.sql.unstructured.text.bad.row.skipping=on; -- このコマンドはスキップを無効にし、以下の SELECT クエリの有効な設定となり、クエリは失敗します。 SET odps.sql.unstructured.text.bad.row.skipping=off; -- このコマンドを使用して、スキップが有効な場合にスキップされた行の詳細を出力できます。クエリが失敗するため、ここでは効果がありません。 SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_flag;クエリは次のエラーで失敗します: FAILED: ODPS-0123131:User defined function exception
柔軟なスキップ
-- 次のコマンドはスキップを有効にしますが、この例の次のコマンドによってすぐに上書きされます。 SET odps.sql.unstructured.text.bad.row.skipping=on; -- このコマンドはスキップを無効にし、テーブルの 'flexible' 設定を上書きします。これは以下の SELECT クエリの有効な設定となり、クエリは失敗します。 SET odps.sql.unstructured.text.bad.row.skipping=off; -- セッションレベルで最大 10 件の不正な行の詳細を出力します。最大値は 1,000 です。値が 0 以下の場合、出力は無効になります。 SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_flexible;クエリは次のエラーで失敗します: FAILED: ODPS-0123131:User defined function exception
固定的なスキップ
-- 'rigid' 設定がすでにスキップを強制しているため、このコマンドは冗長です。 SET odps.sql.unstructured.text.bad.row.skipping=on; -- このコマンドはスキップを無効にしようとしますが、'rigid' テーブル設定は上書きできないため無視されます。 SET odps.sql.unstructured.text.bad.row.skipping=off; -- このコマンドは、'rigid' 設定によってスキップされた最大 10 件の不正な行の詳細を出力します。 SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_rigid;次の結果が返されます:
+------------+------------+ | a | b | +------------+------------+ | 1 | 26 | | 5 | 37 | +------------+------------+
Smart Parse による柔軟な型互換性
OSS 内の CSV 形式の外部テーブルに対して、MaxCompute SQL は読み取りおよび書き込み操作にデータ型 2.0 を使用します。以前は、厳密な形式の値のみがサポートされていました。この機能は、CSV ファイルから幅広い値の形式を読み取るための柔軟な型互換性を提供します。具体的な解析ルールは以下に詳述します。
タイプ | 文字列としての入力 | 文字列としての出力 | 説明 |
BOOLEAN |
説明 解析中に入力に対して |
| 入力文字列がサポートされている値のいずれでもない場合、解析は失敗します。 |
TINYINT |
説明
|
| 8 ビット整数。値が |
SMALLINT | 16 ビット整数。値が | ||
INT | 32 ビット整数。値が | ||
BIGINT | 64 ビット整数。値が 説明 値 | ||
FLOAT |
説明
|
| 特殊な値 (大文字と小文字を区別しない) には、NaN、Inf、-Inf、Infinity、-Infinity が含まれます。値が範囲外の場合、エラーが発生します。精度が制限を超える場合、値は四捨五入されます。 |
DOUBLE |
説明
|
| 特殊な値 (大文字と小文字を区別しない) には、NaN、Inf、-Inf、Infinity、-Infinity が含まれます。値が範囲外の場合、エラーが発生します。精度が制限を超える場合、値は四捨五入されます。 |
DECIMAL (precision, scale) 例:DECIMAL(15,2) |
説明
|
| 整数部分が エラーが報告されます。小数部分がスケールを超える場合、値は四捨五入されて切り捨てられます。 |
CHAR(n) 例:CHAR(7) |
|
| 最大長は 255 です。入力文字列が n より短い場合、末尾にスペースがパディングされますが、これらのスペースは比較時に無視されます。入力文字列が n より長い場合、切り捨てられます。 |
VARCHAR(n) 例:VARCHAR(7) |
|
| 最大長は 65,535 です。入力文字列が n より長い場合、切り捨てられます。 |
STRING |
|
| 最大長は 8 MB です。 |
DATE |
説明
|
|
|
TIMESTAMP_NTZ 説明 OpenCsvSerde は Hive データ形式と互換性がないため、この型をサポートしていません。 |
|
|
|
DATETIME |
| システムのタイムゾーンが Asia/Shanghai であると仮定すると:
|
|
TIMESTAMP |
| (システムのタイムゾーンが Asia/Shanghai であると仮定)
|
|
一般的なルール
どのデータ型でも、CSV データファイル内の空の文字列は、テーブルに読み込まれる際に NULL として解析されます。
サポートされていないデータ型
複雑な型 (STRUCT, ARRAY, MAP):サポートされていません。これらの型の値には、一般的な CSV 区切り文字と競合して解析の失敗を引き起こす可能性のあるコンマ (
,) などの文字が含まれることがよくあります。BINARY および INTERVAL:現在サポートされていません。これらの型のサポートが必要な場合は、MaxCompute のテクニカルサポートにお問い合わせください。
数値型 (INT, DOUBLE など)
INT, SMALLINT, TINYINT, BIGINT, FLOAT, DOUBLE, DECIMAL などの数値データ型に対して、MaxCompute は広範なデフォルトの解析機能を提供します。
基本的な数値文字列のみを解析する必要がある場合は、
tblpropertiesでodps.text.option.smart.parse.levelプロパティをnaiveに設定できます。naive モードでは、パーサーは "123" や "123.456" のような単純な形式のみをサポートします。他の文字列形式を解析するとエラーが発生します。
日付および時刻型 (DATE, TIMESTAMP など)
java.time.format.DateTimeFormatterクラスは、DATE, DATETIME, TIMESTAMP, TIMESTAMP_NTZの 4 つすべての日付および時刻型を処理します。デフォルト形式:MaxCompute には、いくつかの組み込みの解析形式があります。
カスタム形式:
tblpropertiesでodps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.formatプロパティを設定することで、複数の解析形式と 1 つの出力形式を定義できます。ハッシュ記号 (
#) を使用して、複数の解析パターンを区切ります。カスタム形式は組み込み形式よりも優先されます。最初のカスタムパターンが出力に使用されます。
例:DATE 型のカスタム形式文字列を
pattern1#pattern2#pattern3と定義した場合、MaxCompute はpattern1、pattern2、またはpattern3に一致する文字列を解析できます。ただし、ファイルにデータを書き込む場合、出力は常にpattern1で指定された形式を使用します。詳細については、「DateTimeFormatter」をご参照ください。
'z' タイムゾーンパターンに関する重要な注意
特に中国のユーザーは、あいまいさがあるため、カスタム形式で 'z' (タイムゾーン名) を使用しないでください。
代わりに、タイムゾーンパターンには 'x' (ゾーンオフセット) または 'VV' (タイムゾーンID) を使用してください。
例:'CST' は通常、中国では中国標準時 (UTC+8) を意味します。しかし、
java.time.format.DateTimeFormatterが 'CST' を解析すると、米国中部標準時 (UTC-6) として解釈され、予期しない入力または出力結果を引き起こす可能性があります。
例
前提条件
MaxCompute プロジェクト。「MaxCompute プロジェクトの作成」をご参照ください。
MaxCompute プロジェクトと同じリージョンにある OSS バケット。「バケットの作成」および「フォルダーの管理」をご参照ください。MaxCompute は OSS フォルダーを自動的に作成できます。SQL を実行する前に作成する必要はありません。
Alibaba Cloud アカウント、Resource Access Management (RAM) ユーザー、または RAM ロールを介した OSS アクセス権限。「OSS の STS モードでのアクセス認可」をご参照ください。
ご利用の MaxCompute プロジェクトにおける
CreateTable権限。「MaxCompute の権限」をご参照ください。
組み込みテキストパーサーを使用した OSS 外部テーブルの作成
例 1:非パーティションテーブル
外部テーブルを「サンプルデータ」の
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 外部テーブルのスキーマを表示できます。この例では
aliyunodpsdefaultroleRAM ロールを使用します。別の RAM ロールを使用する場合は、aliyunodpsdefaultroleを対象の RAM ロールの名前に置き換え、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/ディレクトリに新しいファイルが表示されることを確認します。データが書き込まれた後、対応する OSS パスに生成された結果ファイル
20250606054845430gpwnhakujm16_M1_1_0_0-0_TableSink1-0-.csv(0.046 KB) と、元のデータファイルvehicle.csv(0.45 KB) を表示できます。
例 2:パーティションテーブル
外部テーブルを「サンプルデータ」の
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;` コマンドを実行して、作成された外部テーブルのスキーマを表示できます。この例では
aliyunodpsdefaultroleRAM ロールを使用します。別の RAM ロールを使用する場合は、aliyunodpsdefaultroleを対象の RAM ロールの名前に置き換え、OSS にアクセスするために必要な権限を付与してください。パーティションデータをインポートします。パーティション化された 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ディレクトリに新しいファイルが生成されていることを確認します。自動生成されたパーティションデータファイル
20250606062610590gocsdsoujm16_M1_1_0_0-0_TableSink1-0-.csvが OSS ファイルリストに表示され、データが対応する OSS のパーティションパスに正常に書き込まれたことを示します。
例 3:圧縮データ
この例では、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;` コマンドを実行して、作成された外部テーブルのスキーマを表示できます。この例では
aliyunodpsdefaultroleRAM ロールを使用します。別の RAM ロールを使用する場合は、aliyunodpsdefaultroleを対象の RAM ロールの名前に置き換え、OSS にアクセスするために必要な権限を付与してください。MaxCompute クライアントを使用して OSS からデータを読み取ります:
説明OSS の圧縮データがオープンソースのデータ形式である場合、SQL ステートメントの前に
set odps.sql.hive.compatible=true;コマンドを追加し、それらを一緒に実行する必要があります。--現在のセッションのみでフルテーブルスキャンを有効にします。 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-mc-test バケットに 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;この例では aliyunodpsdefaultrole RAM ロールを使用します。別の RAM ロールを使用する場合は、aliyunodpsdefaultrole を対象の RAM ロールの名前に置き換え、OSS にアクセスするために必要な権限を付与してください。
コマンドは次の結果を返します:
+----------+--------+------------+
| id | name | tran_amt |
+----------+--------+------------+
| 1 | val1 | 1.1 |
| 2 | value2 | 1.3 |
+----------+--------+------------+列が不一致の外部テーブルの作成
「サンプルデータ」の
oss-mc-testバケットに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-mc-testバケットに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 | 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 | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
カスタム時間型を持つ CSV 外部テーブルの作成
CSV のカスタム時間型の解析および出力形式の詳細については、「Smart Parse による柔軟な型互換性」をご参照ください。
DATE、DATETIME、TIMESTAMP、TIMESTAMP_NTZなど、さまざまな時間データ型を使用する CSV 外部テーブルを作成します。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 | +------------+---------------------+---------------------+------------------------+
よくある質問
列数の不一致エラー
症状
このエラーは、CSV または TSV ファイルの行の列数が、外部テーブルの DDL で定義された列数と一致しない場合に発生します。MaxCompute は
FAILED: ODPS-0123131:User defined function exception - Traceback:java.lang.RuntimeException: SCHEMA MISMATCH:xxxのようなエラーを報告します。解決策
セッションレベルで
odps.sql.text.schema.mismatch.modeパラメーターを設定することで、MaxCompute が不一致をどのように処理するかを制御できます:SET odps.sql.text.schema.mismatch.mode=error:列数の不一致が発生した場合にクエリを失敗させます。これはデフォルトの動作です。SET odps.sql.text.schema.mismatch.mode=truncate:行の列数が外部テーブルの DDL で定義された数より多い場合、余分な列は破棄されます。行の列数が少ない場合、不足している列は NULL で埋められます。