すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:CSV および TSV の外部テーブル

最終更新日:Apr 02, 2026

OSS(Object Storage Service)に格納された 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 ファイルから読み取る場合、または圧縮済み OSS ファイルに書き込む場合、CREATE TABLE ステートメントに with serdeproperties 属性を含める必要があります。詳細については、「with serdeproperties 属性パラメーター」をご参照ください。

圧縮形式

com.aliyun.odps.CsvStorageHandler/

TsvStorageHandler

(組み込み)

org.apache.hadoop.hive.serde2.OpenCSVSerde

(オープンソース)

GZIP

サポート対象

サポート対象

SNAPPY

非サポート

サポート対象

LZO

非サポート

サポート対象

サポートされるスキーマ進化

操作

サポート対象

説明

列の追加

サポート対象

  • デフォルト値を持つ列の追加はサポートされていません。

  • 複雑または入れ子になったデータ型の列の追加はサポートされていません。

列の削除

サポート対象

この操作は推奨されません。スキーマとデータの不一致が発生する可能性があります。

列の順序変更

サポート対象

この操作は推奨されません。スキーマとデータの不一致が発生する可能性があります。

列のデータ型の変更

サポート対象

サポートされるデータ型変換の一覧については、「列のデータ型の変更」をご参照ください。

列名の変更

サポート対象

列コメントの変更

サポート対象

コメントは、最大長 1,024 バイトの有効な文字列である必要があります。それ以外の場合、エラーが発生します。

列の NULL 許容性の変更

非サポート

この操作はサポートされていません。列はデフォルトで NULL 許容です。

パラメーター構成

CSV または TSV 外部テーブルのスキーマは、ファイルの列と**位置**によってマッピングされます。OSS ファイル内の列数が外部テーブルのスキーマの列数と一致しない場合、odps.sql.text.schema.mismatch.mode パラメーターを使用して、不一致の行の処理方法を指定できます。

  • odps.sql.text.schema.mismatch.modetruncate に設定した場合、列の変更には以下の効果があります:

    • 新しいスキーマに準拠するデータは、期待通りに読み取られます。

    • 既存のデータ(古いスキーマを使用)は、新しいスキーマに基づいて読み取られます。

      たとえば、テーブルに列を追加した場合、その列に関する履歴データは、テーブルを読み取る際に NULL として表示されます。

  • odps.sql.text.schema.mismatch.modeignore に設定した場合、列の変更には以下の効果があります:

    • 新しいスキーマに準拠するデータは、期待通りに読み取られます。

    • 既存のデータ(古いスキーマを使用)は、新しいスキーマに基づいて読み取られます。

      たとえば、テーブルに列を追加した場合、新しい列がない履歴データの行全体が、テーブルを読み取る際に破棄されます。

  • odps.sql.text.schema.mismatch.modeerror に設定した場合、列の変更には以下の効果があります:

    • 新しいスキーマに準拠するデータは、期待通りに読み取られます。

    • 既存のデータ(古いスキーマを使用)は、新しいスキーマに基づいて読み取られます。

      たとえば、テーブルに列を追加した場合、新しい列がない履歴データを読み取ろうとするとエラーが発生します。

外部テーブルの作成

構文

組み込みテキストパーサー

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 圧縮プロパティ。 MaxCompute が GZIP 圧縮ファイルを読み取れるようにするには、このプロパティを True に設定します。それ以外の場合、読み取り操作は失敗します。

  • True

  • False

False

odps.text.option.gzip.output.enabled

このプロパティを使用して、OSS に GZIP 圧縮形式でデータを書き込みます。

CSV および TSV 圧縮プロパティ。 OSS への書き込み時にデータを圧縮するには、このプロパティを True に設定します。それ以外の場合、データは非圧縮で書き込まれます。

  • True

  • False

False

odps.text.option.header.lines.count

このプロパティを使用して、OSS の CSV または TSV ファイルの先頭 N 行をスキップします。

データ読み取り時に、ファイルの先頭からスキップするヘッダー行の数を指定します。

非負の整数

0

odps.text.option.null.indicator

このプロパティを使用して、データ内の NULL 値を表すカスタム文字列を定義します。

MaxCompute は、指定された文字列を NULL 値として解析します。

たとえば、ファイル内の \NNULL として解釈するには、このプロパティを \\N に設定します。ここで、最初の \ はエスケープ文字です。この設定により、a,\N,ba, NULL, b として解析されます。

文字列

空文字列

odps.text.option.ignore.empty.lines

このプロパティを使用して、CSV または TSV ファイル内の空行の処理方法を定義します。

True の場合、MaxCompute はデータファイル内の空行を無視します。False の場合、空行を読み取ります。

  • True

  • False

True

odps.text.option.encoding

データファイルがデフォルトの UTF-8 エンコーディングを使用していない場合に、このプロパティを使用します。

ここで指定するエンコーディングは、ファイルの実際のエンコーディングと一致している必要があります。不一致があると、読み取りに失敗します。

  • UTF-8

  • UTF-16

  • US-ASCII

  • GBK

UTF-8

odps.text.option.delimiter

このプロパティを使用して、CSV または TSV ファイルの列区切り文字を指定します。

指定した区切り文字がデータファイル内の列を正しく分離することを確認してください。そうでないと、データの配置がずれる可能性があります。

1 文字

カンマ (,)

odps.text.option.use.quote

CSV または TSV ファイルのフィールドに改行(CRLF)、二重引用符、または列区切り文字が含まれている場合に、このプロパティを使用します。

CSV ファイルのフィールドに改行、二重引用符(二重引用符をエスケープするには、" の前にもう 1 つの " を追加する必要があります)、またはカンマが含まれている場合、そのフィールド全体を二重引用符("")で囲む必要があります。このパラメーターは、CSV 列区切り文字 " を認識するかどうかを指定します。

  • True

  • False

False

odps.sql.text.option.flush.header

このプロパティを使用して、OSS の各ファイルブロックの先頭行にテーブルヘッダーを書き込みます。

このプロパティは、CSV ファイルにのみ適用されます。

  • True

  • False

False

odps.sql.text.schema.mismatch.mode

データファイルの行の列数が外部テーブルのスキーマと異なる場合に、このプロパティを使用します。

テーブルスキーマと列数が一致しない行の処理方法を指定します。

注: この機能は、odps.text.option.use.quoteTrue に設定した場合には動作しません。

  • error:エラーを報告し、クエリを中止します。

  • truncate:行の列数がスキーマより多い場合、MaxCompute は余分な列を破棄します。列数が少ない場合、不足している列には null が入力されます。

  • ignore:不一致の行全体を破棄します。

error

組み込みオープンソースデータパーサー(OpenCSVSerde)

separatorChar

TEXTFILE として格納された CSV データの列区切り文字を指定するために、このプロパティを使用します。

列区切り文字を指定します。

1 文字

カンマ (,)

quoteChar

CSV データのフィールドに区切り文字や改行などの特殊文字が含まれている場合に、このプロパティを使用します。

フィールドを囲むために使用する文字を指定します。

1 文字

なし

escapeChar

TEXTFILE として格納された CSV データのエスケープ文字を指定するために、このプロパティを使用します。

フィールド内の特殊文字をエスケープするために使用する文字を指定します。

1 文字

なし

tblproperties パラメーター

適用可能なパーサー

パラメーター

使用例

説明

デフォルト

組み込みオープンソースデータパーサー(OpenCSVSerde)

skip.header.line.count

TEXTFILE として格納された CSV ファイルの先頭 N 行をスキップするために、このプロパティを使用します。

データ読み取り時に、ファイルの先頭からスキップするヘッダー行の数を指定します。

非負の整数

なし

skip.footer.line.count

TEXTFILE として格納された CSV ファイルの末尾 N 行をスキップするために、このプロパティを使用します。

データ読み取り時に、ファイルの末尾からスキップするフッター行の数を指定します。

非負の整数

なし

mcfed.mapreduce.output.fileoutputformat.compress

このプロパティを使用して、圧縮された TEXTFILE データを OSS に書き込みます。

TEXTFILE 圧縮プロパティ。 True に設定すると、MaxCompute は書き込み時にデータを圧縮します。それ以外の場合、データは非圧縮で書き込まれます。

  • True

  • False

False

mcfed.mapreduce.output.fileoutputformat.compress.codec

このプロパティを使用して、圧縮された TEXTFILE データを OSS に書き込む際の圧縮コーデックを指定します。

TEXTFILE 圧縮プロパティ。 TEXTFILE 出力用の圧縮コーデックを指定します。

注: MaxCompute は、property_value 列に記載された 4 種類のコーデックのみをサポートしています。

  • com.hadoop.compression.lzo.LzoCodec

  • com.hadoop.compression.lzo.LzopCodec

  • org.apache.hadoop.io.compress.SnappyCodec

  • com.aliyun.odps.io.compress.SnappyRawCodec

なし

io.compression.codecs

OSS データファイルが Raw-Snappy 形式で圧縮されている場合に、このプロパティを使用します。

MaxCompute が Raw-Snappy 圧縮データを読み取れるようにします。この設定がないと、読み取り操作は失敗します。

com.aliyun.odps.io.compress.SnappyRawCodec

なし

odps.text.option.bad.row.skipping

OSS に格納された CSV ファイルのダーティデータをスキップするために、このプロパティを使用します。

MaxCompute がダーティデータと見なされる行をスキップするか、エラーを報告するかを制御します。

  • rigid:行のスキップを強制します。この設定はセッションレベルまたはプロジェクトレベルで上書きできません。

  • flexible:**柔軟な**行スキップを有効にします。この設定は、セッションレベルまたはプロジェクトレベルの構成で上書きできます。

なし

データの書き込み

MaxCompute における書き込み構文の詳細については、「書き込み構文」をご参照ください。

クエリおよび分析

  • SELECT 構文の詳細については、「クエリ構文」をご参照ください。

  • クエリプランの最適化の詳細については、「クエリの最適化」をご参照ください。

  • 詳細については、「BadRowSkipping」をご参照ください。

BadRowSkipping

BadRowSkipping 機能により、クエリの失敗を引き起こす可能性のある CSV データ内の不良行をスキップできます。この設定はエラー処理を制御するものであり、基盤となるデータ形式の解析には影響しません。

パラメーター

  • テーブルレベルのパラメーター:odps.text.option.bad.row.skipping

    • rigid:スキップを強制します。この設定は、セッションレベルまたはプロジェクトレベルの構成で上書きできません。

    • flexible:スキップを有効にします。この設定は **柔軟** であり、セッションレベルまたはプロジェクトレベルの構成で上書きできます。

  • セッション/プロジェクト レベルのパラメーター

    • odps.sql.unstructured.text.bad.row.skipping パラメーターは、flexible のテーブルレベルのパラメーターを上書きできますが、rigid の場合は上書きできません。

      • on機能を有効化します。テーブルで機能が構成されていない場合、デフォルトで有効になります。

      • off機能を無効化します。テーブルが flexible として構成されている場合、機能は無効になります。それ以外の場合は、テーブルパラメーターの設定が使用されます。

      • <null> または無効な入力:テーブルレベルの構成が使用されます。

    • odps.sql.unstructured.text.bad.row.skipping.debug.num:Logview で stdout に出力するエラー結果の数を指定します。

      • 最大値は 1000 です。

      • 値が <=0 の場合、この機能は無効になります。

      • 値が無効な場合、この機能は無効になります。

  • セッションレベルのパラメーターとテーブルプロパティーの相互作用

    テーブルプロパティー

    セッションフラグ

    結果

    rigid

    on

    オン、強制的にオン

    off

    <null>、無効な値、またはパラメーターが未設定

    flexible

    on

    オン

    off

    オフ、セッションにより無効化

    <null>、無効な値、またはパラメーターが未設定

    オン

    未設定

    on

    オン、セッションにより有効化

    off

    オフ

    <null>、無効な値、またはパラメーターが未設定

  1. データの準備

    不良行を含むテストデータファイル csv_bad_row_skipping.csv を、OSS のディレクトリ(例: oss-mc-test/badrow/)にアップロードします。

  2. 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'  -- スキップを強制的に有効化します。
    );
  3. クエリ結果の検証

    パラメーター未設定

    -- 次のコマンドによりスキップが有効化されますが、この例では直後のコマンドにより直ちに上書きされます。
    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

  • "true"/"false"

  • "T"/"F"

  • "1"/"0"

  • "Yes"/"No"

  • "Y"/"N"

  • ""(空文字列は NULL として解析されます。)

説明

解析時に、入力に対して trim() 操作が実行されます。

  • "true"/"false"

  • "true"/"false"

  • "true"/"false"

  • "true"/"false"

  • "true"/"false"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

入力文字列がサポートされる値のいずれでもない場合、解析は失敗します。

TINYINT

  • "0"

  • "1"

  • "-100"

  • "1,234,567"(桁区切り記号表記;カンマは文字列の先頭または末尾に置くことはできません)

  • "1_234_567"(Java スタイル;アンダースコアは文字列の先頭または末尾に置くことはできません)

  • "0.3e2"(指数表記;値が整数である場合にのみ解析されます。それ以外の場合はエラーが発生します)

  • "-1e5"(指数表記)

  • "0xff"(16 進数、大文字小文字を区別しない)

  • "0b1001"(2 進数、大文字小文字を区別しない)

  • "4/2"(分数;値が整数である場合にのみ解析されます。それ以外の場合はエラーが発生します)

  • "1000%"(パーセント;値が整数である場合にのみ解析されます。それ以外の場合はエラーが発生します)

  • "1000‰"(パーミル;値が整数である場合にのみ解析されます。それ以外の場合はエラーが発生します)

  • "1,000 $"(通貨記号付き)

  • "$ 1,000"(通貨記号付き)

  • "3M"(K8s スタイル、基数 1000 の単位)

  • "2Gi"(K8s スタイル、基数 1024 の単位)

  • ""(空文字列は NULL として解析されます。)

説明
  • 解析時に、入力に対して trim() 操作が実行されます。

  • 桁区切り記号表記(例:"1,234,567")を使用する場合、CSV 区切り文字をカンマ以外の文字に設定する必要があります。「with serdeproperties 属性」の odps.text.option.delimiter の使用方法をご参照ください。

  • サポートされる K8s スタイルの基数 1000 の単位には、K、M、G、P、T があります。基数 1024 の単位には、Ki、Mi、Gi、Pi、Ti があります。詳細については、「resource-management」をご参照ください。

  • サポートされる通貨記号には、$/¥/€/£/₩/USD/CNY/EUR/GBP/JPY/KRW/IDR/RP があります。

  • "0""1""-100"、および "" は、naive mode でも正しく解析できます。

  • "0"

  • "1"

  • "-100"

  • "1234567"

  • "1234567"

  • "30"

  • "-100000"

  • "255"

  • "9"

  • "2"

  • "10"

  • "1"

  • "1000"

  • "1000"

  • "3000000"(1M = 1000*1000)

  • "2147483648"(1 Gi = 1024*1024*1024)

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

8 ビット整数。値が [-128, 127] の範囲外の場合、エラーが発生します。

SMALLINT

16 ビット整数。値が [-32768, 32767] の範囲外の場合、エラーが発生します。

INT

32 ビット整数。値が [-2147483648, 2147483647] の範囲外の場合、エラーが発生します。

BIGINT

64 ビット整数。値が [-9223372036854775807, 9223372036854775807] の範囲外の場合、エラーが発生します。

説明

SQL エンジンの制限により、値 -2<sup>63</sup>-9223372036854775808)はサポートされる範囲外です。

FLOAT

  • "3.14"

  • "0.314e1"(指数表記)

  • "2/5"(分数)

  • "123.45%"(パーセント)

  • "123.45‰"(パーミル)

  • "1,234,567.89"(桁区切り記号表記)

  • "1,234.56 $"(通貨記号付き)

  • "$ 1,234.56"(通貨記号付き)

  • "1.2M"(K8s スタイル、基数 1000 の単位)

  • "2Gi"(K8s スタイル、基数 1024 の単位)

  • "NaN"(大文字小文字を区別しない)

  • "Inf"(大文字小文字を区別しない)

  • "-Inf"(大文字小文字を区別しない)

  • "Infinity"(大文字小文字を区別しない)

  • "-Infinity"(大文字小文字を区別しない)

  • ""(空文字列は NULL として解析されます。)

説明
  • 解析時に、入力に対して trim() 操作が実行されます。

  • "3.14""0.314e1""NaN""Infinity""-Infinity"、および "" は、naive mode でも正しく解析できます。

  • "3.14"

  • "3.14"

  • "0.4"

  • "1.2345"

  • "0.12345"

  • "1234567.89"

  • "1234.56"

  • "1234.56"

  • "1200000"

  • "2147483648"

  • "NaN"

  • "Infinity"

  • "-Infinity"

  • "Infinity"

  • "-Infinity"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

特殊値(大文字小文字を区別しない)には、NaN、Inf、-Inf、Infinity、-Infinity があります。値が範囲外の場合、エラーが発生します。精度が上限を超える場合、値は四捨五入されます。

DOUBLE

  • "3.1415926"

  • "0.314e1"(指数表記)

  • "2/5"(分数)

  • "123.45%"(パーセント)

  • "123.45‰"(パーミル)

  • "1,234,567.89"(桁区切り記号表記)

  • "1,234.56 $"(通貨記号付き)

  • "$ 1,234.56"(通貨記号付き)

  • "1.2M"(K8s スタイル、基数 1000 の単位)

  • "2Gi"(K8s スタイル、基数 1024 の単位)

  • "NaN"(大文字小文字を区別しない)

  • "Inf"(大文字小文字を区別しない)

  • "-Inf"(大文字小文字を区別しない)

  • "Infinity"(大文字小文字を区別しない)

  • "-Infinity"(大文字小文字を区別しない)

  • ""(空文字列は NULL として解析されます。)

説明
  • 解析時に、入力に対して trim() 操作が実行されます。

  • "3.1415926""0.314e1""NaN""Infinity""-Infinity"、および "" は、naive mode でも正しく解析できます。

  • "3.1415926"

  • "3.14"

  • "0.4"

  • "1.2345"

  • "0.12345"

  • "1234567.89"

  • "1234.56"

  • "1234.56"

  • "1200000"

  • "2147483648"

  • "NaN"

  • "Infinity"

  • "-Infinity"

  • "Infinity"

  • "-Infinity"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

特殊値(大文字小文字を区別しない)には、NaN、Inf、-Inf、Infinity、-Infinity があります。値が範囲外の場合、エラーが発生します。精度が上限を超える場合、値は四捨五入されます。

DECIMAL

(precision, scale)

例:DECIMAL(15,2)

  • "3.358"

  • "2/5"(分数)

  • "123.45%"(パーセント)

  • "123.45‰"(パーミル)

  • "1,234,567.89"(桁区切り記号表記)

  • "1,234.56 $"(通貨記号付き)

  • "$ 1,234.56"(通貨記号付き)

  • "1.2M"(K8s スタイル、基数 1000 の単位)

  • "2Gi"(K8s スタイル、基数 1024 の単位)

  • ""(空文字列は NULL として解析されます。)

説明
  • 解析時に、trim() 操作が入力に対して実行されます。

  • "3.358" および "" は、naive mode でも正しく解析できます。

  • "3.36"(四捨五入)

  • "0.4"

  • "1.23"(四捨五入)

  • "0.12"(四捨五入)

  • "1234567.89"

  • "1234.56"

  • "1234.56"

  • "1200000"

  • "2147483648"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

整数部の桁数が precision - scale を超えるとエラーが発生します。小数部の桁数が指定された scale を超える場合、値は四捨五入されます。

エラーが報告されます。小数部の桁数が scale を超える場合、値は四捨五入および切り捨てられます。

CHAR(n)

例:CHAR(7)

  • "abcdefg"

  • "abcdefghijklmn"

  • "abc"

  • ""(空文字列は NULL として解析されます。)

  • "abcdefg"

  • "abcdefg"(残りの文字列は切り捨てられます。)

  • "abc____"(4 つの空白文字で埋められます。空白文字は _ で表されます。)

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

最大長は 255 です。入力文字列が n より短い場合、末尾に空白文字で埋められますが、比較時にはこれらの空白文字は無視されます。入力文字列が n より長い場合、切り捨てられます。

VARCHAR(n)

例:VARCHAR(7)

  • "abcdefg"

  • "abcdefghijklmn"

  • "abc"

  • ""(空文字列は NULL として解析されます。)

  • "abcdefg"

  • "abcdefg"(残りの文字列は切り捨てられます。)

  • "abc"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

最大長は 65,535 です。入力文字列が n より長い場合、切り捨てられます。

STRING

  • "abcdefg"

  • "abc"

  • ""(空文字列は NULL として解析されます。)

  • "abcdefg"

  • "abc"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

最大長は 8 MB です。

DATE

  • "yyyy-MM-dd"(例:"2025-02-21")

  • "yyyyMMdd"(例:"20250221")

  • "MMM d,yyyy"(例:"Oct 1,2025")

  • "MMMM d,yyyy"(例:"October 1,2025")

  • "yyyy年M月d日"(例:"2025年10月1日")

  • ""(空文字列は NULL として解析されます。)

説明

odps.text.option.date.io.format プロパティを設定して、解析フォーマットを制御できます。たとえば、フォーマットを 'dd/MM/yyyy#yyyy--MM--dd' に設定すると、MaxCompute は '21/02/2025''2025--02--21' のような文字列を解析できます。

  • "2000-01-01"

  • "2000-01-01"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

  • この型には時刻情報が含まれていないため、タイムゾーンの変更は出力に影響しません。デフォルトの出力フォーマットは "yyyy-MM-dd" です。

  • odps.text.option.date.io.format プロパティを設定して、カスタムの解析および出力フォーマットを定義できます。定義した最初のパターンが、出力に使用されます。パターン構文については、「DateTimeFormatter」をご参照ください。

TIMESTAMP_NTZ

説明

OpenCsvSerde はこの型をサポートしていません。Hive データ形式と互換性がないためです。

  • ナノ秒部分は 0~9 桁になります。MaxCompute が組み込みでサポートするフォーマットは以下のとおりです:

    • "yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]"(例:"2000-01-01 00:00:00.123")

    • "yyyy-MM-ddTHH:mm:ss[.SSSSSSSSS]"(例:"2000-01-01T00:00:00.123456789")

    • "yyyyMMddHHmmss"(例:"20000101000000")

    • ""(空文字列は NULL として解析されます。)

  • odps.text.option.timestamp_ntz.io.format プロパティを設定して、解析フォーマットを制御できます。たとえば、フォーマットを 'ddMMyyyy-HHmmss' に設定すると、MaxCompute は '31102024-103055' のような文字列を解析できます。

  • "2000-01-01 00:00:00.123000000"

  • "2000-01-01 00:00:00.123456789"

  • "2000-01-01 00:00:00.000000000"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

  • この型はナノ秒精度のタイムスタンプを表します。セッションのタイムゾーンには影響を受けず、出力は標準の UTC タイムゾーンで行われます。デフォルトの出力フォーマットは "yyyy-MM-dd HH:mm:ss.SSSSSSSSS" です。

  • odps.text.option.timestamp_ntz.io.format プロパティを設定して、カスタムの解析および出力フォーマットを定義できます。パターン構文については、「DateTimeFormatter」をご参照ください。

DATETIME

  • ミリ秒部分は 0~3 桁になります。[x] はタイムゾーンオフセットを表します。システムタイムゾーンが Asia/Shanghai であると仮定した場合、MaxCompute が組み込みでサポートするフォーマットは以下のとおりです:

    • "yyyy-MM-dd HH:mm:ss[.SSS][x]"(例:"2000-01-01 00:00:00.123")

    • "yyyy-MM-ddTHH:mm:ss[.SSS][x]"(例:"2000-01-01T00:00:00.123+0000")

    • "yyyyMMddHHmmss[x]"(例:"20000101000000+0000")

    • ""(空文字列は NULL として解析されます。)

  • odps.text.option.datetime.io.format プロパティを設定して、解析フォーマットを制御できます。たとえば、フォーマットを 'yyyyMMdd-HHmmss.SSS' に設定すると、MaxCompute は '20241031-103055.123' のような文字列を解析できます。

システムタイムゾーンが Asia/Shanghai であると仮定した場合:

  • "2000-01-01 00:00:00.123+0800"

  • "2000-01-01 08:00:00.123+0800"

  • "2000-01-01 08:00:00.000+0800"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

  • この型はミリ秒精度のタイムスタンプを表します。出力値はセッションのタイムゾーンに影響を受けます。デフォルトの出力フォーマットは "yyyy-MM-dd HH:mm:ss.SSSx" です。

  • odps.sql.timezone プロパティを設定して、システムタイムゾーンを変更することで、出力値のタイムゾーンオフセットを制御できます。

  • odps.text.option.datetime.io.format プロパティを設定して、カスタムの解析および出力フォーマットを定義できます。パターン構文については、「DateTimeFormatter」をご参照ください。

TIMESTAMP

  • ナノ秒部分は 0~9 桁になります。[x] はタイムゾーンオフセットを表します。システムタイムゾーンが Asia/Shanghai であると仮定した場合、MaxCompute が組み込みでサポートするフォーマットは以下のとおりです:

    • "yyyy-MM-dd HH:mm:ss[.SSSSSSSSS][x]"(例:"2000-01-01 00:00:00.123456")

    • "yyyy-MM-ddTHH:mm:ss[.SSSSSSSSS][x]"(例:"2000-01-01T00:00:00.123+0000")

    • "yyyyMMddHHmmss[x]"(例:"20000101000000+0000")

    • ""(空文字列は NULL として解析されます。)

  • odps.text.option.timestamp.io.format プロパティを設定して、解析フォーマットを制御できます。たとえば、フォーマットを 'yyyyMMdd-HHmmss' に設定すると、MaxCompute は '20240910-103055' のような文字列を解析できます。

(システムタイムゾーンが Asia/Shanghai であると仮定)

  • "2000-01-01 00:00:00.123456000+0800"

  • "2000-01-01 08:00:00.123000000+0800"

  • "2000-01-01 08:00:00.000000000+0800"

  • ""(NULL 値は CSV ファイルに空文字列として書き込まれます。)

  • この型はナノ秒精度のタイムスタンプを表します。出力値はセッションのタイムゾーンに影響を受けます。デフォルトの出力フォーマットは "yyyy-MM-dd HH:mm:ss.SSSSSSSSSx" です。

  • odps.sql.timezone プロパティを設定して、システムタイムゾーンを変更することで、出力値のタイムゾーンオフセットを制御できます。

  • odps.text.option.timestamp.io.format プロパティを設定して、カスタムの解析および出力フォーマットを定義できます。パターン構文については、「DateTimeFormatter」をご参照ください。

  • 一般ルール

    • 任意のデータ型において、CSV データファイル内の空文字列は、テーブルに読み取られる際に NULL として解析されます。

  • サポートされていないデータ型

    • 複合型(STRUCT、ARRAY、MAP):サポートされていません。これらの型の値には、カンマ(,)などの文字が含まれることが多く、一般的な CSV 区切り文字と競合して解析が失敗する可能性があります。

    • BINARY および INTERVAL:現在サポートされていません。これらの型のサポートが必要な場合は、MaxCompute のテクニカルサポートにお問い合わせください。

  • 数値型(INT、DOUBLE など)

    • INT、SMALLINT、TINYINT、BIGINT、FLOAT、DOUBLE、DECIMAL などの数値データ型に対して、MaxCompute は広範なデフォルト解析機能を提供します。

    • 基本的な数値文字列のみを解析する必要がある場合、odps.text.option.smart.parse.level プロパティを naive に設定できます。tblproperties 内で naive モードを設定すると、パーサーは "123" や "123.456" のような単純なフォーマットのみをサポートします。他の文字列フォーマットを解析しようとするとエラーが発生します。

  • 日付および時刻型(DATE、TIMESTAMP など)

    • java.time.format.DateTimeFormatter クラスが、DATE、DATETIME、TIMESTAMP、TIMESTAMP_NTZ の 4 つの日付および時刻型すべてを処理します。

    • デフォルトフォーマット:MaxCompute にはいくつかの組み込み解析フォーマットがあります。

    • カスタムフォーマット:

      • odps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.format プロパティを tblproperties で設定することで、複数の解析フォーマットと 1 つの出力フォーマットを定義できます。

      • ハッシュ記号(#)を使用して、複数の解析パターンを区切ります。

      • カスタムフォーマットは、組み込みフォーマットよりも優先されます。最初のカスタムパターンが出力に使用されます。

      • 例:DATE 型のカスタムフォーマット文字列を pattern1#pattern2#pattern3 として定義した場合、MaxCompute は pattern1pattern2、または pattern3 に一致する文字列を解析できます。ただし、ファイルへの書き込み時には、常に pattern1 で指定されたフォーマットが出力に使用されます。詳細については、「DateTimeFormatter」をご参照ください。

  • 'z' タイムゾーンパターンに関する重要な注意事項

    • 中国のユーザー向けに特に、カスタムフォーマットで 'z'(タイムゾーン名)を使用しないしないでください。あいまいさがあるため、特に中国のユーザーはカスタムフォーマットで 'z'(タイムゾーン名)を使用しないでください。

    • 代わりに、タイムゾーンパターンには 'x'(ゾーンオフセット)または 'VV'(タイムゾーン ID)を使用してください。

    • 例:中国では 'CST' は通常、中国標準時(UTC+8)を意味します。しかし、java.time.format.DateTimeFormatter が 'CST' を解析すると、米国中部標準時(UTC-6)として解釈され、予期しない入出力結果を引き起こす可能性があります。

前提条件

    組み込みテキストパーサーを使用した OSS 外部テーブルの作成

    例 1:非パーティションテーブル

    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 RAM ロールを使用しています。別の RAM ロールを使用する場合は、aliyunodpsdefaultrole を対象の RAM ロールの名前に置き換え、OSS へのアクセスに必要な権限を付与してください。

    2. 非パーティションテーブルをクエリします。

      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          |
      +------------+------------+------------+------------+------------------+-------------------+------------+----------------+
    3. 非パーティションテーブルにデータを書き込み、データが正常に書き込まれたことを確認します。

      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/ ディレクトリに新しいファイルが表示されることを確認します。image

    例 2:パーティションテーブル

    1. 外部テーブルをサンプルデータ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 RAM ロールを使用しています。別の RAM ロールを使用する場合は、aliyunodpsdefaultrole を対象の RAM ロールの名前に置き換え、OSS へのアクセスに必要な権限を付与してください。

    2. パーティションデータをインポートします。パーティション化された 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');
    3. パーティションテーブルをクエリします。

      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         |
      +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
    4. パーティションテーブルにデータを書き込み、データが正常に書き込まれたことを確認します。

      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 ディレクトリに新しいファイルが生成されることを確認します。image

    例 3:圧縮データ

    この例では、GZIP 圧縮された CSV 外部テーブルを作成し、読み取りおよび書き込み操作を実行する方法を示します。

    1. 内部テーブルを作成し、後続の書き込みテスト用にテストデータを挿入します。

      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');
    2. 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;` コマンドを実行して、作成された外部テーブルのスキーマを表示できます。

      この例では、aliyunodpsdefaultrole RAM ロールを使用しています。別の RAM ロールを使用する場合は、aliyunodpsdefaultrole を対象の RAM ロールの名前に置き換え、OSS へのアクセスに必要な権限を付与してください。

    3. 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          |
      +------------+------------+------------+
    4. 内部テーブルからデータを読み取り、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        |
    +----------+--------+------------+

    列が不一致の外部テーブルの作成

    1. サンプルデータ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
    2. 外部テーブルを作成します。

      1. 列数が一致しない行の処理方法を 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/';
      2. 列数が一致しない行の処理方法を 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/';
      3. テーブル内のデータをクエリします。

        • 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 外部テーブルを作成し、ヘッダー行とフッター行を無視してコンマ区切りファイルを読み取る方法を示します。

    1. サンプルデータ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
    2. 外部テーブルを作成し、区切り文字としてカンマを指定し、ヘッダー行とフッター行を無視するパラメーターを設定します。

      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"
      )
      ;
    3. 外部テーブルからデータを読み取ります。

      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 の柔軟な型互換性」をご参照ください。

    1. DATEDATETIMETIMESTAMPTIMESTAMP_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');
    2. データが挿入された後、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
    3. 再度データをクエリして結果を表示します。

      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 で埋められます。