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

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

最終更新日:Sep 18, 2026

Object Storage Service (OSS) に保存されている CSV および TSV データの外部テーブルを作成、読み取り、書き込みする方法について説明します。

注意事項

  • OSS 外部テーブルはクラスタープロパティをサポートしていません。

  • 単一ファイルのサイズは 2 GB を超えることはできません。2 GB を超えるファイルは分割する必要があります。

  • MaxCompute と OSS は同じリージョンにある必要があります。

サポートされているデータ型

MaxCompute のデータ型の詳細については、「データ型バージョン 1.0」および「データ型バージョン 2.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 ファイルの読み取りまたは書き込みを行う場合、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.modetruncate に設定されている場合、列の変更は次の効果をもたらします:

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

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

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

  • odps.sql.text.schema.mismatch.modeignore に設定されている場合、列の変更は次の効果をもたらします:

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

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

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

  • odps.sql.text.schema.mismatch.modeerror に設定されている場合、列の変更は次の効果をもたらします:

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

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

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

権限の説明

  • OSS 外部テーブルにアクセスする際、Alibaba Cloud アカウント (root ユーザー)、RAM ユーザー、または RAM ロールのいずれを使用するかにかかわらず、データは odps.properties.rolearn パラメーターで指定されたロールを介してアクセスされます。したがって、RAM ロールを作成し、ターゲットの OSS バケットにアクセスするための権限を付与し、そのロールの ARN を odps.properties.rolearn パラメーターで設定する必要があります。詳細については、「パラメーター」をご参照ください。

  • ビジネス要件に基づいて、同一アカウントまたはクロスアカウントのアクセスを権限付与できます。よりきめ細かなアクセス制御を行うために、カスタム権限付与ポリシーを使用することを推奨します。詳細については、「外部データソースの権限付与」をご参照ください。

外部テーブルの作成

構文

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

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

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

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 ファイルの列区切り文字を指定する場合に、このプロパティを使用します。

データの不整合を防ぐために、指定したデリミタがデータファイル内の列を正しく区切っていることを確認してください。

単一文字

コンマ (,)

odps.text.option.use.quote

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

CSV ファイルのフィールドに改行、二重引用符 (エスケープするために " の前にもう一つ " を追加する必要があります)、またはコンマが含まれる場合、フィールド全体を列区切り文字として二重引用符 ("") で囲む必要があります。このパラメーターは、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 は余分な列を破棄します。列数が少ない場合、MaxCompute は欠落している列を null で埋めます。

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

error

odps.text.option.zstd.input.enabled

ZSTD 形式で圧縮された CSV または TSV ファイルを読み取る場合に、このプロパティを使用します。

CSV および TSV 圧縮プロパティ。MaxCompute が ZSTD 圧縮ファイルを読み取るには、このプロパティを True に設定します。それ以外の場合、読み取り操作は失敗します。

  • True

  • False

False

odps.text.option.zstd.output.enabled

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

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

  • True

  • False

False

odps.text.option.snappy.input.enabled

SNAPPY で圧縮された CSV または TSV ファイルを読み取る必要がある場合に、このプロパティを追加します。

(SnappyRawCodec)。

CSV および TSV 圧縮プロパティ。MaxCompute は、このパラメーターが True に設定されている場合にのみ圧縮ファイルを読み取ることができます。それ以外の場合、読み取り操作は失敗します。

  • True

  • False

False

odps.text.option.snappy.output.enabled

データを書き込む必要がある場合に、このプロパティを追加します。

SNAPPY (SnappyRawCodec) で圧縮された OSS。

CSV および TSV 圧縮プロパティ。このパラメーターが True に設定されている場合、MaxCompute はデータを SNAPPY 圧縮で OSS に書き込みます。それ以外の場合、データは非圧縮で書き込まれます。

  • True

  • False

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

  • True

  • False

False

mcfed.mapreduce.output.fileoutputformat.compress.codec

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

ファイル名に .bz2、.deflate、.snappy、.gz、または .zstd のサフィックスが含まれる圧縮された CSV/TSV ファイルを読み取る場合、追加の構成は不要です。

TEXTFILE 圧縮プロパティ。TEXTFILE データファイルの圧縮方法を設定します。

  • com.hadoop.compression.lzo.LzoCodec

  • com.hadoop.compression.lzo.LzopCodec

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

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

  • org.apache.hadoop.io.compress.odps.ZstandardCodec

  • org.apache.hadoop.io.compress.GzipCodec

  • org.apache.hadoop.io.compress.BZip2Codec

  • org.apache.hadoop.io.compress.DeflateCodec

なし

odps.text.option.bad.row.skipping

OSS に保存されている CSV ファイル内のダーティデータをスキップする場合に、このプロパティを使用します。

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

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

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

なし

ホワイトリストとブラックリスト

MaxCompute の OSS 外部テーブルは、ホワイトリストとブラックリストによるフィルタリングをサポートしています。tblproperties でホワイトリストとブラックリストのパラメーターを設定することで、ディレクトリから読み取るファイルをフィルタリングできます。詳細については、「ホワイトリストとブラックリスト」をご参照ください。

データの書き込み

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

クエリと分析

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

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

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

BadRowSkipping

BadRowSkipping 機能を使用すると、クエリの失敗原因となる CSV データ内の不正な行をスキップできます。この設定はエラー処理を制御し、基になるデータ形式の解析方法には影響しません。

パラメーター

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

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

    • 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 の場合、この機能は無効になります。

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

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

    tbl プロパティ

    セッションフラグ

    結果

    rigid

    on

    On、強制的に On

    off

    <null>、無効な値、またはパラメーターが構成されていない

    flexible

    on

    On

    off

    Off、セッションによって無効化

    <null>、無効な値、またはパラメーターが構成されていない

    On

    構成されていない

    on

    On、セッションによって有効化

    off

    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         | 
    +------------+------------+

スマート解析による柔軟な型互換性

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" (バイナリ、大文字と小文字を区別しません)

  • "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 があります。詳細については、「リソース管理」をご参照ください。

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

  • 文字列 "0""1""-100"、および "" は、naive モードでも正しく解析できます。

  • "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] の範囲外の場合、エラーが発生します。

説明

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

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 モードでも正しく解析できます。

  • "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 モードでも正しく解析できます。

  • "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 モードでも正しく解析できます。

  • "3.36" (四捨五入)

  • "0.4"

  • "1.23" (四捨五入)

  • "0.12" (四捨五入)

  • "1234567.89"

  • "1234.56"

  • "1234.56"

  • "1200000"

  • "2147483648"

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

整数部分が precision - 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")

  • "" (空の文字列は 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 は広範なデフォルトの解析機能を提供します。

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

  • 日付と時刻の型 (DATE, TIMESTAMP など)

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

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

    • カスタム形式:

      • tblpropertiesodps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.format プロパティを設定することで、複数の解析形式と 1 つの出力形式を定義できます。

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

      • カスタム形式は組み込み形式よりも優先されます。最初のカスタムパターンが出力に使用されます。

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

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

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

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

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

CSV ファイルの分割ロジック

組み込み CSV/TSV パーサー (OpenCSVSerde)

組み込み CSV/TSV パーサー (OpenCSVSerde) は、CSV ファイルの各データ行が \r\n などの文字で区切られ、列に \r\n が含まれていないことを要求します。並列分割とデータ整合性のロジックは次のとおりです:

  • まず、ファイルは分割サイズによって分割され、一部の行は途中で切断される可能性があります。

  • 後続のワーカーが分割を消費する際、最初の分割を除くすべての分割は、先頭の部分的または完全な行を積極的にスキップします。

  • 各ワーカーは、次の分割の範囲内であっても、末尾の部分的または完全な行を積極的に消費する必要があります。

このパーサーは並列分割をサポートしますが、引用符のエスケープはサポートしていません。

オープンソース CSV パーサー (CsvStorageHandler / TsvStorageHandler)

オープンソース CSV パーサー (CsvStorageHandler / TsvStorageHandler) は、CSV/TSV ファイルを読み取る際に引用符のエスケープを考慮し、\r\n をサポートします。ネストされた引用符や \r\n などの特殊文字が引用符内に現れるシナリオを処理できます。

たとえば、データ "a\ra","b\nb","cc""cc" では、\r\n と二重引用符が正しく解析および出力され、複数行にまたがる値をサポートします。ただし、実際の改行位置はデータ解析を通じてのみ決定できるため、ファイルを単純に \r\n で分割することはできません。その結果、単一ファイルの並列消費はサポートされていません。

データ列に \r\n が含まれず、\r\n が行区切り文字としてのみ使用されていることを確認した場合、odps.sql.unstructured.data.single.file.split.enabled を設定することで並列分割を有効にできます。この場合、大きなファイルは分割サイズによって複数の分割に分割され、組み込みの Text Extractor が自動的に改行境界に整列してデータ整合性を確保します。

結論

  • データに行区切り文字として扱えない \r\n が含まれている場合、組み込み CSV/TSV パーサーのみを使用できます。

  • 逆に、単一の大きなファイルを並列で分割する必要がある場合は、オープンソース CSV Serde パーサーのみを使用できます。

前提条件

  • MaxCompute プロジェクトが作成されていること

  • OSS バケットとフォルダが利用可能であること。詳細については、「バケットの作成」および「フォルダの管理」をご参照ください。

    MaxCompute は OSS でのフォルダの自動作成をサポートしています。SQL ステートメントに外部テーブルとユーザー定義関数 (UDF) が含まれる場合、単一のステートメントを使用してテーブルの読み取りと書き込み、および UDF の使用ができます。フォルダを手動で作成することもできます。

    MaxCompute は特定のリージョンにのみデプロイされています。クロスリージョンデータ接続に関する潜在的な問題を避けるため、ご利用の OSS バケットが MaxCompute プロジェクトと同じリージョンにあることを確認してください。
  • 権限付与

    • OSS にアクセスする権限が必要です。Alibaba Cloud アカウント (root ユーザー)、Resource Access Management (RAM) ユーザー、または RAM ロールを使用して OSS 外部テーブルにアクセスできます。権限付与の詳細については、「OSS の STS モードでのアクセス権限付与」をご参照ください。

    • MaxCompute プロジェクトで CreateTable 権限が必要です。テーブル権限の詳細については、「MaxCompute の権限」をご参照ください。

組み込みテキストパーサーを使用した 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/ ディレクトリに新しいファイルが表示されることを確認します。

    データが書き込まれた後、対応する OSS パスで生成された結果ファイル 20250606054845430gpwnhakujm16_M1_1_0_0-0_TableSink1-0-.csv (0.046 KB) と、元のデータファイル vehicle.csv (0.45 KB) を表示できます。

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

    自動生成されたパーティションデータファイル 20250606062610590gocsdsoujm16_M1_1_0_0-0_TableSink1-0-.csv が OSS ファイルリストに表示され、データが対応する OSS のパーティションパスに正常に書き込まれたことを示します。

例 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',
  'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
)
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',
        'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole')
      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" = ",",
    'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    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 のカスタム時刻型の解析および出力形式の詳細については、「スマート解析による柔軟な型互換性」をご参照ください。

  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/'
    WITH serdeproperties (
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    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 で埋められます。