Skip to content
Last updated

CSVパーサー関数

Treasure DataのIntegration用CSVパーサープラグインはCSVデータを解析します。以下の表で説明する15のオプションがあります。詳細については、CSV parser pluginを参照してください。

オプション説明
delimiterデリミタ文字。任意の1バイト文字を指定できます。例えば、CSVでは \t、TSVでは
use_string_literal設定で \t などの特殊文字を使用する場合にチェックします
quote引用符で囲まれた値を囲む文字。\0 を設定するとクォートが無効になります。
escape特殊文字をエスケープするためのエスケープ文字。\0 を設定するとエスケープが無効になります。
skip_header_lines最初にスキップする行数。ファイルにヘッダー行がある場合は1を設定します。
null_string値がこの文字列の場合、NULLに変換します。例えば、mysqldumpで作成されたCSVファイルの場合は \N を設定します
trim_if_not_quotedtrueの場合、値がクォート文字で囲まれていなければスペースを除去します
comment_line_marker行がこの文字列で始まる場合、その行をスキップします
allow_optional_columnstrueの場合、不足している列にnullを設定します。それ以外の場合、列数が不足している行はスキップされます。CSVパーサーは解析時に正確にどの列が不足しているかを判断できないため、不足している列は最後の列として扱われます。
allow_extra_columnstrueの場合、余分な列を無視します。それ以外の場合、列数が多すぎる行はスキップされます。
max_quoted_size_limitクォートされた値の最大バイト数。値がこの制限を超える場合、その行はスキップされます
stop_on_invalid_recordファイルに無効なレコード(無効なタイムスタンプなど)が含まれている場合、バルクロードトランザクションを停止します
default_timezone値自体にタイムゾーンの記述が含まれていない場合のタイムスタンプ列のタイムゾーン(例:Asia/Tokyo)
newline改行文字(CRLF、LF、またはCR)
line_delimiter_recognizedtrueの場合、指定された改行文字が新しい行として処理され、その文字もデータとして保持されます。
charset文字エンコーディング(例:ISO-8859-1、UTF-8)。CSVパーサーのcharsetオプションでサポートされる値を参照してください。
quotes_in_quoted_fieldsクォートされたフィールド内の不正なエスケープされていないクォート文字の処理方法を指定します。ACCEPT_ONLY_RFC4180_ESCAPEDまたはACCEPT_STRAY_QUOTES_ASSUMING_NO_DELIMITERS_IN_FIELDSのいずれかを指定してください。
columns列(以下を参照)

columnsオプションは列のリストを宣言します。このCSVパーサープラグインはヘッダー行を無視します。列の順序はCSV列のマッピング(順序による)に使用され、ヘッダー(存在する場合)は破棄されます。

説明
name列の名前
type列の型(以下を参照)。
boolean : trueまたはfalse
long : 64ビット符号付き整数
timestamp : ナノ秒精度の日付と時刻
double : 64ビット浮動小数点数
string : 文字列
formattypeがtimestampの場合のタイムスタンプのフォーマット

Quotes in Quoted Fieldsオプション

quotes_in_quotes_fieldsオプションは、不正なエスケープされていない迷子のクォート文字の処理方法を指定します。

名前説明
ACCEPT_ONLY_RFC4180_ESCAPEDデフォルト。CSV解析はRFC 4180に準拠しています。

ACCEPT_STRAY_QUOTES_ASSUMING_NO_DELIMITERS_IN_FIELDS

引用符の間にある迷子のクォートをそのまま受け入れます。引用符の中にデリミタがある場合、動作は未定義です。

例えば、フィールドが "a"b" の場合、中央のクォートは通常の文字として扱われ、結果は a"b になります。ただし、フィールドが "a""b" の場合、中央の2つのクォートはエスケープされたクォートと見なされ、結果は a"b になります。

CSVパーサーの設定

guessを使用して列設定を自動的に生成できます。または、以下の例のようにparserセクションを設定します:

in:
...
  parser:
    type: csv
    charset: UTF-8
    newline: CRLF
    delimiter: "\t"
    quote: '"'
    escape: '"'
    null_string: 'NULL'
    skip_header_lines: 1
    comment_line_marker: '#'
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out:
...

CSVパーサーのユースケース例

CSVパーサー関数のユースケース例を以下に示します:

CSVパーサーのユースケース例 1

パーサー関数でシンプルなCSVを使用する例です。

ソースデータの例

id,name,price,tag,timestamp
1,"A green door",11.50,"green","2016-01-02"
2,"A blue door",12.50,"blue","2016-01-03"
3,"A red door",13.50,"red","2016-01-04"
4,"A pink door",14.50,"pink","2016-01-05"
5,"A white door",15.50,"white","2016-01-06"
6,"A black door",16.50,"black","2016-01-07"
7,"A yellow door",17.50,"yellow","2016-01-08"
8,"A purple door",18.50,"purple","2016-01-09"
in:
...
parser:
  charset: UTF-8
  newline: CRLF
  type: csv
  delimiter: ","
  quote: "\""
  escape: "\""
  trim_if_not_quoted: false
  skip_header_lines: 1
  allow_extra_columns: false
  allow_optional_columns: false
  columns:
  - {name: id, type: long}
  - {name: name, type: string}
  - {name: price, type: double}
  - {name: tag, type: string}
  - {name: timestamp, type: timestamp, format: '%Y-%m-%d'}
filters: []
out: {mode: append}
exec: {}

previewコマンドで解析されたCSVデータを確認できます。

$ td connector:preview load.yml

データにtime列がない場合は、add_timeフィルターオプションを使用して追加できます。詳細については、add_timeフィルター関数を参照してください。

$ td connector:issue load.yml \
--database <database name> \
--table <table name>  \
--time-column timestamp --auto-create-table

CSVパーサーのユースケース例 2

以下のオプションの使用例です:

  • null_string
  • trim_if_not_quoted
  • comment_line_marker
  • max_quoted_size_limit

ソースデータは以下の通りです。

id,name,price,tag,timestamp
1,"A green door",11.50,"green","2016-01-02"
2,"A blue door",12.50,"blue","2016-01-03"
3,"A red door",13.50,"red","2016-01-04"
4,"A pink door",14.50,"pink","2016-01-05"
5,"A white door",15.50,"   white   ","2016-01-06"
6,"A black door",16.50,    black    ,"2016-01-07"
7,"A yellow door",17.50,"yellow","2016-01-08"
8,"A purple doooooooooooooooooooooooor",18.50,"purple","2016-01-09"

以下のload.ymlを使用した場合:

in:
...
parser:
  charset: UTF-8
  newline: CRLF
  type: csv
  delimiter: ","
  quote: "\""
  escape: "\""
  skip_header_lines: 1
  null_string "red"
  trim_if_not_quoted: true
  comment_line_marker: "2"
  max_quoted_size_limit: 20
  columns:
  - {name: id, type: long}
  - {name: name, type: string}
  - {name: price, type: double}
  - {name: tag, type: string}
  - {name: timestamp, type: timestamp, format: '%Y-%m-%d'}
filters: []
out: {mode: append}
exec: {}

プレビュー結果は以下の通りです。

$ td connector:preview load.yml
+---------+-----------------+--------------+---------------+---------------------------+
| id:long | name:string     | price:double | tag:string    | timestamp:timestamp       |
+---------+-----------------+--------------+---------------+---------------------------+
| 1       | "A green door"  | 11.5         | "green"       | "2016-01-02 00:00:00 UTC" |
| 3       | "A red door"    | 13.5         | nil           | "2016-01-04 00:00:00 UTC" |
| 4       | "A pink door"   | 14.5         | "pink"        | "2016-01-05 00:00:00 UTC" |
| 5       | "A white door"  | 15.5         | "   white   " | "2016-01-06 00:00:00 UTC" |
| 6       | "A black door"  | 16.5         | "black"       | "2016-01-07 00:00:00 UTC" |
| 7       | "A yellow door" | 17.5         | "yellow"      | "2016-01-08 00:00:00 UTC" |
+---------+-----------------+--------------+---------------+---------------------------+
  • null_stringは"red"タグをnilに置換しました。("A red door"は完全一致ではないため対象外です。)

  • trim_if_not_quotedは"black"タグの前後のスペースを除去しました。クォートされていないためです。("white"タグはクォートされているため対象外です。)

  • comment_line_markerは"blue"のレコードをスキップしました。行が"2"で始まるためです。

  • max_quoted_size_limitは"purple"のレコードをスキップしました。名前が値を超えたためです。

CSVパーサーのユースケース例 3

allow_optional_columnsをFALSE(デフォルト)またはTRUEに設定した場合の解析結果への影響の例です。

ソースデータは以下の通りです。

id,name,price,tag,timestamp,additional
1,"A green door",11.50,"green","2016-01-02",aaa
2,"A blue door",12.50,"blue","2016-01-03",aaa
3,"A red door",13.50,"red","2016-01-04"
4,"A pink door",14.50,"pink","2016-01-05",aaa
5,"A white door",15.50,"white","2016-01-06",aaa
6,"A black door",16.50,"black","2016-01-07"
7,"A yellow door",17.50,"yellow","2016-01-08",aaa
8,"A purple door",18.50,"purple","2016-01-09",aaa

load.ymlの設定は以下の通りです。

in:
...
parser:
  ...
  allow_optional_columns: [ false / true ]
  columns:
  - {name: id, type: long}
  - {name: name, type: string}
  - {name: price, type: double}
  - {name: tag, type: string}
  - {name: timestamp, type: timestamp, format: '%Y-%m-%d'}
  - {name: additional, type: string}
filters: []
out: {mode: append}
exec: {}

falseの結果では、"additional"列の値がないため"red"と"black"の行がありません。

$ td connector:preview load.yml
+---------+-----------------+--------------+------------+---------------------------+-------------------+
| id:long | name:string     | price:double | tag:string | timestamp:timestamp       | additional:string |
+---------+-----------------+--------------+------------+---------------------------+-------------------+
| 1       | "A green door"  | 11.5         | "green"    | "2016-01-02 00:00:00 UTC" | "aaa"             |
| 2       | "A blue door"   | 12.5         | "blue"     | "2016-01-03 00:00:00 UTC" | "aaa"             |
| 4       | "A pink door"   | 14.5         | "pink"     | "2016-01-05 00:00:00 UTC" | "aaa"             |
| 5       | "A white door"  | 15.5         | "white"    | "2016-01-06 00:00:00 UTC" | "aaa"             |
| 7       | "A yellow door" | 17.5         | "yellow"   | "2016-01-08 00:00:00 UTC" | "aaa"             |
| 8       | "A purple door" | 18.5         | "purple"   | "2016-01-09 00:00:00 UTC" | "aaa"             |
+---------+-----------------+--------------+------------+---------------------------+-------------------+

一方、trueの結果ではnullが設定されます。

+---------+-----------------+--------------+------------+---------------------------+-------------------+
| id:long | name:string     | price:double | tag:string | timestamp:timestamp       | additional:string |
+---------+-----------------+--------------+------------+---------------------------+-------------------+
| 1       | "A green door"  | 11.5         | "green"    | "2016-01-02 00:00:00 UTC" | "aaa"             |
| 2       | "A blue door"   | 12.5         | "blue"     | "2016-01-03 00:00:00 UTC" | "aaa"             |
| 3       | "A red door"    | 13.5         | "red"      | "2016-01-04 00:00:00 UTC" | nil               |
| 4       | "A pink door"   | 14.5         | "pink"     | "2016-01-05 00:00:00 UTC" | "aaa"             |
| 5       | "A white door"  | 15.5         | "white"    | "2016-01-06 00:00:00 UTC" | "aaa"             |
| 6       | "A black door"  | 16.5         | "black"    | "2016-01-07 00:00:00 UTC" | nil               |
| 7       | "A yellow door" | 17.5         | "yellow"   | "2016-01-08 00:00:00 UTC" | "aaa"             |
| 8       | "A purple door" | 18.5         | "purple"   | "2016-01-09 00:00:00 UTC" | "aaa"             |
+---------+-----------------+--------------+------------+---------------------------+-------------------+

CSVパーサーのユースケース例 4

allow_extra_columnsをFALSE(デフォルト)またはTRUEに設定した場合の解析結果への影響の例です。

ソースデータは以下の通りです:

id,name,price,tag,timestamp,additional
1,"A green door",11.50,"green","2016-01-02",aaa
2,"A blue door",12.50,"blue","2016-01-03",aaa
3,"A red door",13.50,"red","2016-01-04"
4,"A pink door",14.50,"pink","2016-01-05",aaa
5,"A white door",15.50,"white","2016-01-06",aaa
6,"A black door",16.50,"black","2016-01-07"
7,"A yellow door",17.50,"yellow","2016-01-08",aaa
8,"A purple door",18.50,"purple","2016-01-09",aaa

load.ymlの設定は以下の通りです:

in:
...
parser:
  ...
  allow_extra_columns: [ false / true ]
  columns:
  - {name: id, type: long}
  - {name: name, type: string}
  - {name: price, type: double}
  - {name: tag, type: string}
  - {name: timestamp, type: timestamp, format: '%Y-%m-%d'}
filters: []
out: {mode: append}
exec: {}

falseの結果では、"additional"列がcolumnsに定義されておらず、他の行に未定義の列値があるため、"red"と"black"の行のみが表示されます。

$ td connector:preview load.yml
+---------+----------------+--------------+------------+---------------------------+
| id:long | name:string    | price:double | tag:string | timestamp:timestamp       |
+---------+----------------+--------------+------------+---------------------------+
| 3       | "A red door"   | 13.5         | "red"      | "2016-01-04 00:00:00 UTC" |
| 6       | "A black door" | 16.5         | "black"    | "2016-01-07 00:00:00 UTC" |
+---------+----------------+--------------+------------+---------------------------+

一方、trueの結果ではすべての行が"additional"列なしで表示されます。

$ td connector:preview load.yml
+---------+-----------------+--------------+------------+---------------------------+
| id:long | name:string     | price:double | tag:string | timestamp:timestamp       |
+---------+-----------------+--------------+------------+---------------------------+
| 1       | "A green door"  | 11.5         | "green"    | "2016-01-02 00:00:00 UTC" |
| 2       | "A blue door"   | 12.5         | "blue"     | "2016-01-03 00:00:00 UTC" |
| 3       | "A red door"    | 13.5         | "red"      | "2016-01-04 00:00:00 UTC" |
| 4       | "A pink door"   | 14.5         | "pink"     | "2016-01-05 00:00:00 UTC" |
| 5       | "A white door"  | 15.5         | "white"    | "2016-01-06 00:00:00 UTC" |
| 6       | "A black door"  | 16.5         | "black"    | "2016-01-07 00:00:00 UTC" |
| 7       | "A yellow door" | 17.5         | "yellow"   | "2016-01-08 00:00:00 UTC" |
| 8       | "A purple door" | 18.5         | "purple"   | "2016-01-09 00:00:00 UTC" |
+---------+-----------------+--------------+------------+---------------------------+

CSVパーサーのユースケース例 5

クォートおよびエスケープ文字として \0 を指定する例です。

ソースデータは以下の通りです:

id,name,price,tag,timestamp
1,"A green door",11.50,"green","2016-01-02"
2,"A blue door",12.50,"blue",2016-01-03
3,"A \"red\" door",13.50,"red",2016-01-04
4,"A pink door",14.50,"pink",2016-01-05
in:
...
parser:
  charset: UTF-8
  newline: CRLF
  type: csv
  delimiter: ","
  quote: "\0"
  escape: "\0"
  trim_if_not_quoted: false
  skip_header_lines: 1
  allow_extra_columns: false
  allow_optional_columns: false
  columns:
  - {name: id, type: long}
  - {name: name, type: string}
  - {name: price, type: double}
  - {name: tag, type: string}
  - {name: timestamp, type: timestamp, format: '%Y-%m-%d'}
filters: []
out: {mode: append}
exec: {}
  • すべてのクォートがパーサーに"クォート文字"として指定されていないため、結果に表示されます。
  • 行1はquoteの値が \0 に設定されているため表示されません。クォートにより"2016-01-02"が無効なタイムスタンプになります。
  • 行4の埋め込みクォートとスラッシュはパーサーに"クォート文字"として指定されていないため、結果に表示されます。
$ td connector:preview load.yml
+---------+-----------------+--------------+------------+---------------------+
| id:long | name:string     | price:double | tag:string | timestamp:timestamp |
+---------+-----------------+--------------+------------+---------------------+
| 2       | "A blue door"   | 12.5         | "blue"     | 2016-01-03 00:00:00 |
| 3       | "A \"red\" door"| 13.5         | "red"      | 2016-01-04 00:00:00 |
| 4       | "A pink door"   | 14.5         | "pink"     | 2016-01-05 00:00:00 |
+---------+-----------------+--------------+------------+---------------------+