本トピックでは、CSV および TSV 形式の Object Storage Service (OSS) 外部テーブルを作成、読み取り、書き込みする方法について説明します。
適用範囲
OSS 外部テーブルはクラスタープロパティをサポートしていません。
単一ファイルのサイズは 2 GB を超えることはできません。2 GB を超えるファイルは分割する必要があります。
MaxCompute と OSS は同じリージョンにある必要があります。
サポートされるデータの型
MaxCompute のデータの型の詳細については、「データの型 V1.0」および「データの型 V2.0」をご参照ください。
スマート解析の詳細については、「スマート解析による柔軟な型互換性」をご参照ください。
データの型 | 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 プロパティを CREATE TABLE 文に追加できます。詳細については、「with serdeproperties パラメーター」をご参照ください。
圧縮フォーマット | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (組み込みテキストデータパーサ) | org.apache.hadoop.hive.serde2.OpenCSVSerde (組み込みオープンソースデータパーサ) |
GZIP | ||
SNAPPY | ||
LZO |
スキーマ進化のサポート
操作タイプ | サポート | 説明 |
列の追加 |
| |
列の削除 | この操作は、スキーマとデータの間に不一致を引き起こす可能性があるため、推奨されません。 | |
列の順序変更 | この操作は、スキーマとデータの間に不一致を引き起こす可能性があるため、推奨されません。 | |
列のデータの型変更 | データの型変換テーブルについては、「列のデータの型変更」をご参照ください。 | |
列名の変更 | ||
列のコメント変更 | コメントは 1024 バイト以下の有効な文字列である必要があります。そうでない場合、エラーが報告されます。 | |
列の NOT NULL プロパティの変更 | この操作はサポートされていません。デフォルト値は Nullable です。 |
パラメーター設定
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 パラメーター
適用パーサ | 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 形式で、ファイルの最初の N 行を無視する必要がある場合、このプロパティを追加します。 | MaxCompute が OSS データファイルを読み取るとき、指定された行数を無視します。 | 非負の整数。 | 0 | |
odps.text.option.null.indicator | OSS データファイルが CSV または TSV 形式で、ファイル内の NULL 値の解析ルールを定義する必要がある場合、このプロパティを追加します。 | このパラメーターで指定された文字列は、SQL で NULL として解析されます。 たとえば、ファイル内の | 文字列 | 空の文字列 | |
odps.text.option.ignore.empty.lines | OSS データファイルが CSV または TSV 形式で、ファイル内の空行の処理ルールを定義する必要がある場合、このプロパティを追加します。 | このパラメーターが True に設定されている場合、MaxCompute はデータファイル内の空行を無視します。そうでない場合、空行が読み取られます。 |
| True | |
odps.text.option.encoding | OSS データファイルが CSV または TSV 形式で、そのエンコード形式がデフォルトでない場合、このプロパティを追加します。 | ここで指定されたエンコード形式が 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 ファイルのデータ列数が、外部テーブルのスキーマ列数と一致しません。 | 列数が不一致の行の処理方法を指定します。 注:この機能は、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 | なし | |
odps.text.option.bad.row.skipping | OSS データファイルが CSV 形式で、ファイル内のダーティデータをスキップする必要がある場合、このプロパティを追加します。 | MaxCompute が OSS データファイルを読み取るとき、ダーティデータをスキップするかどうかを選択できます。 |
| なし |
データの書き込み
MaxCompute の書き込み構文の詳細については、「書き込み構文」をご参照ください。
クエリと分析
SELECT 構文の詳細については、「クエリ構文」をご参照ください。
クエリプランの最適化の詳細については、「クエリの最適化」をご参照ください。
BadRowSkipping の詳細については、「BadRowSkipping」をご参照ください。
BadRowSkipping
CSV データにダーティデータが存在する場合、BadRowSkipping 機能を使用して、エラーを引き起こすデータをスキップするかどうかを指定するパラメーターを設定できます。この機能を有効または無効にしても、基になるデータ形式の解析には影響しません。
パラメーター設定
テーブルレベルのパラメーター
odps.text.option.bad.row.skippingrigid:スキップロジックは実行する必要があり、セッションレベルまたはプロジェクトレベルの設定で上書きすることはできません。flexible:データプレーンで柔軟なスキップを有効にします。この設定は、セッションレベルまたはプロジェクトレベルの設定で上書きできます。
セッションレベルまたはプロジェクトレベルのパラメーターodps.sql.unstructured.text.bad.row.skipping:このパラメーターは、柔軟なテーブルレベルのパラメーターを上書きできますが、固定のテーブルレベルのパラメーターは上書きできません。on:アクティブに有効化。このパラメーターがテーブルに構成されていない場合、自動的に有効になります。off:アクティブに無効化。テーブルレベルのパラメーターが flexible に設定されている場合、この機能は無効になります。その他の場合、テーブルレベルのパラメーターが優先されます。<null>/入力が無効な場合:動作はテーブルレベルの構成によってのみ決定されます。
odps.sql.unstructured.text.bad.row.skipping.debug.num:Logview の標準出力 (stdout) に出力できるエラー結果の数を指定します。最大値は 1000 です。
値が 0 以下の場合、この機能は無効になります。
入力が無効な場合、この機能は無効になります。
セッションレベルとテーブルレベルのパラメーター間の相互作用
tbl プロパティ
セッションフラグ
結果
rigid
on
オン、強制的に有効化
off
<null>、無効な値、またはこのパラメーターが構成されていない
flexible
on
オン
off
オフ、セッションによって無効化
<null>、無効な値、またはこのパラメーターが構成されていない
オン
構成されていない
on
ステータス:セッションで有効化
off
オフ
<null>、無効な値、またはこのパラメーターが構成されていない
使用例
データ準備
ダーティデータを含むテストデータファイル csv_bad_row_skipping.csv を OSS の
oss-mc-test/badrow/ディレクトリにアップロードします。CSV 外部テーブルの作成
以下の 3 つのシナリオは、テーブルレベルのパラメーターとセッションレベルのフラグの異なる組み合わせを説明しています。
テーブルパラメーター:
odps.text.option.bad.row.skipping = flexible/rigid/<not specified>セッションフラグ:
odps.sql.unstructured.text.bad.row.skipping = on/off/<not specified>
テーブルレベルのパラメーターが構成されていない
-- テーブルレベルのパラメーターは構成されていません。エラーは発生時に報告されます。動作はセッションレベルのフラグによって制御されます。 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://databucketpath>';テーブルレベルのパラメーターはエラー行をスキップするように設定されているが、セッションレベルで無効にできる
-- テーブルレベルのパラメーターはエラー行をスキップするように設定されていますが、セッションレベルのフラグによってアクティブに無効にできます。 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://databucketpath>' 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://databucketpath>' tblproperties ( 'odps.text.option.bad.row.skipping' = 'rigid' -- 強制的に有効化。 );クエリ結果の検証
テーブルレベルのパラメーターが構成されていない
-- セッションレベルで有効化。 SET odps.sql.unstructured.text.bad.row.skipping=on; -- セッションレベルで無効化。テーブルレベルのパラメーターが 'flexible' に設定されている場合、この機能は無効になります。テーブルレベルのパラメーターが 'rigid' に設定されている場合、この設定は効果がありません。 SET odps.sql.unstructured.text.bad.row.skipping=off; -- セッションレベルで問題のある行データを出力。最大 1,000 行まで出力できます。値が 0 以下の場合、出力は無効になります。 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' に設定されている場合、この機能は無効になります。テーブルレベルのパラメーターが 'rigid' に設定されている場合、この設定は効果がありません。 SET odps.sql.unstructured.text.bad.row.skipping=off; -- セッションレベルで問題のある行データを出力。最大 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
テーブルレベルのパラメーターはエラー行をスキップするように設定されており、セッションレベルで無効にできない
-- セッションレベルで有効化。 SET odps.sql.unstructured.text.bad.row.skipping=on; -- セッションレベルで無効化。テーブルレベルのパラメーターが 'flexible' に設定されている場合、この機能は無効になります。テーブルレベルのパラメーターが 'rigid' に設定されている場合、この設定は効果がありません。 SET odps.sql.unstructured.text.bad.row.skipping=off; -- セッションレベルで問題のある行データを出力。最大 1,000 行まで出力できます。値が 0 以下の場合、出力は無効になります。 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 | +------------+------------+
スマート解析による柔軟な型互換性
CSV 形式の OSS 外部テーブルに対して、MaxCompute SQL はデータの型 V2.0 を使用して読み取りおよび書き込み操作を実行します。MaxCompute は現在、CSV ファイル内のさまざまな型の値と互換性があります。詳細は次の表のとおりです:
型 | 文字列としての入力 | 文字列としての出力 | 説明 |
BOOLEAN |
説明 入力は、解析中に |
| 値が列挙にない場合、解析は失敗します。 |
TINYINT |
説明
|
| 8 ビット整数。値が |
SMALLINT | 16 ビット整数。値が | ||
INT | 32 ビット整数。値が | ||
BIGINT | 64 ビット整数。値が 説明 SQL エンジンの制限により、 | ||
FLOAT |
説明
|
| 特殊な値 (大文字と小文字を区別しない) には、NaN、Inf、-Inf、Infinity、-Infinity が含まれます。値が値の範囲外の場合、エラーが報告されます。精度を超えた場合、値は四捨五入されて切り捨てられます。 |
DOUBLE |
説明
|
| 特殊な値 (大文字と小文字を区別しない) には、NaN、Inf、-Inf、Infinity、-Infinity が含まれます。値が値の範囲外の場合、エラーが報告されます。精度を超えた場合、値は四捨五入されて切り捨てられます。 |
DECIMAL (precision, scale) 例:DECIMAL(15,2) |
説明
|
| 整数部の桁数が 、エラーが報告されます。小数部がスケールを超えた場合、値は四捨五入されて切り捨てられます。 |
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 として解析されます。
サポートされていないデータの型
複雑な型 (STRUCT、ARRAY、MAP):サポートされていません。これは、これらの複雑な型の値が、カンマ (
,) などの一般的な CSV デリミタと容易に競合し、解析エラーを引き起こす可能性があるためです。BINARY および INTERVAL 型:サポートされていません。これらの型を使用するには、MaxCompute のテクニカルサポートにお問い合わせください。
数値型 (INT、DOUBLE など)
INT、SMALLINT、TINYINT、BIGINT、FLOAT、DOUBLE、DECIMAL のデータの型では、デフォルトの解析機能は柔軟です。
基本的な数値文字列のみを解析したい場合は、
tblpropertiesでodps.text.option.smart.parse.levelパラメーターをnaiveに設定できます。これにより、パーサは「123」や「123.456」などの一般的な数値文字列のみをサポートするように構成されます。他の形式の文字列を解析するとエラーが報告されます。
日付と時刻の型 (DATE、TIMESTAMP など)
4 つの日付または時刻関連の型、
DATE、DATETIME、TIMESTAMP、TIMESTAMP_NTZはすべて、基盤となるコードでjava.time.format.DateTimeFormatterを使用して処理されます。デフォルト形式:MaxCompute には、いくつかの組み込みのデフォルト解析形式があります。
カスタム形式:
tblpropertiesでodps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.formatを設定して、複数の解析形式と 1 つの出力形式をカスタマイズできます。複数の解析形式をシャープ記号 (
#) で区切ることができます。カスタム形式は、MaxCompute の組み込み解析形式よりも優先度が高くなります。最初のカスタム形式が出力形式として使用されます。
例:DATE 型の形式文字列を
pattern1#pattern2#pattern3としてカスタマイズした場合、pattern1、pattern2、またはpattern3に準拠する文字列を解析できます。ただし、ファイルに書き込むときは、pattern1形式が使用されます。詳細については、「DateTimeFormatter」をご参照ください。
重要:「z」タイムゾーン形式に関する注意
特に中国のユーザーの場合、「z」(タイムゾーン名) は一部のコンテキストであいまいになる可能性があるため、カスタムタイムゾーン形式として使用しないことを推奨します。
代わりに、「x」(ゾーンオフセット) または「VV」(タイムゾーン ID) をタイムゾーンパターンとして使用することを推奨します。
例:「CST」は通常、中国では中国標準時 (UTC+8) を表します。しかし、「CST」が
java.time.format.DateTimeFormatterによって解析されると、米国中部標準時 (UTC-6) として識別されます。これにより、予期しない入力または出力結果が生じる可能性があります。
使用例
前提条件
OSS バケットとフォルダが利用可能であること。詳細については、「バケットの作成」および「フォルダの管理」をご参照ください。
MaxCompute は OSS での自動フォルダ作成をサポートしています。SQL 文に外部テーブルとユーザー定義関数 (UDF) が含まれている場合、単一の文を使用してテーブルの読み取りと書き込みを行い、UDF を使用できます。フォルダを手動で作成することもできます。
MaxCompute は特定のリージョンにのみデプロイされます。リージョン間のデータ接続に関する潜在的な問題を回避するために、ご利用の OSS バケットが MaxCompute プロジェクトと同じリージョンにあることを確認してください。
権限付与
OSS にアクセスする権限が必要です。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 外部テーブルのスキーマを表示できます。この例で使用されるロールは
aliyunodpsdefaultroleです。別のロールを使用する場合は、aliyunodpsdefaultroleをご利用のロール名に置き換え、そのロールに 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/を確認します。新しいファイルが生成されています。
例 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; コマンドを実行して、作成された外部テーブルのスキーマを表示できます。この例で使用されるロールは
aliyunodpsdefaultroleです。別のロールを使用する場合は、aliyunodpsdefaultroleをご利用のロール名に置き換え、そのロールに 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を確認します。新しいファイルが生成されています。
例 3:圧縮データ
この例では、CSV 形式で GZIP 圧縮された外部テーブルを作成し、読み取りおよび書き込み操作を実行する方法を示します。
内部テーブルを作成し、その後の書き込みテストのためにテストデータを書き込みます。
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');CSV 形式で GZIP 圧縮された外部テーブルを作成し、「サンプルデータ」の
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; コマンドを実行して、作成された外部テーブルのスキーマを表示できます。この例で使用されるロールは
aliyunodpsdefaultroleです。別のロールを使用する場合は、aliyunodpsdefaultroleをご利用のロール名に置き換え、そのロールに 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 ファイルの最初の行をテーブルヘッダーとして指定して 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 です。別のロールを使用する場合は、aliyunodpsdefaultrole をご利用のロール名に置き換え、そのロールに OSS へのアクセス権限を付与してください。
次の結果が返されます:
+----------+--------+------------+
| id | name | tran_amt |
+----------+--------+------------+
| 1 | val1 | 1.1 |
| 2 | value2 | 1.3 |
+----------+--------+------------+列数が OSS データの列数と一致しない OSS 外部テーブルの作成
「サンプルデータ」から
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 外部テーブルを作成し、カンマ区切りファイルを読み取り、最初と最後の行を無視する方法を示します。
「サンプルデータ」から
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 | 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 の時刻型のカスタム解析および出力形式の詳細については、「スマート解析による柔軟な型互換性」をご参照ください。
各時刻データの型 (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 データの読み取り時に「列数の不一致」エラーが報告される
症状
CSV/TSV ファイルの列数が外部テーブルの DDL の列数と一致しない場合、CSV/TSV データを読み取るときに「列数の不一致」エラーが報告されます。例:
FAILED: ODPS-0123131:User defined function exception - Traceback:java.lang.RuntimeException: SCHEMA MISMATCH:xxx。解決策
セッションレベルで
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 で埋められます。