# CSVパーサー関数

Treasure DataのIntegration用CSVパーサープラグインはCSVデータを解析します。以下の表で説明する15のオプションがあります。詳細については、[CSV parser plugin](http://www.embulk.org/docs/built-in.html#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_quoted | trueの場合、値がクォート文字で囲まれていなければスペースを除去します |
| comment_line_marker | 行がこの文字列で始まる場合、その行をスキップします |
| allow_optional_columns | trueの場合、不足している列にnullを設定します。それ以外の場合、列数が不足している行はスキップされます。CSVパーサーは解析時に正確にどの列が不足しているかを判断できないため、不足している列は最後の列として扱われます。 |
| allow_extra_columns | trueの場合、余分な列を無視します。それ以外の場合、列数が多すぎる行はスキップされます。 |
| max_quoted_size_limit | クォートされた値の最大バイト数。値がこの制限を超える場合、その行はスキップされます |
| stop_on_invalid_record | ファイルに無効なレコード（無効なタイムスタンプなど）が含まれている場合、バルクロードトランザクションを停止します |
| default_timezone | 値自体にタイムゾーンの記述が含まれていない場合のタイムスタンプ列のタイムゾーン（例：Asia/Tokyo） |
| newline | 改行文字（CRLF、LF、またはCR） |
| line_delimiter_recognized | trueの場合、指定された改行文字が新しい行として処理され、その文字もデータとして保持されます。 |
| charset | 文字エンコーディング（例：ISO-8859-1、UTF-8）。[CSVパーサーのcharsetオプションでサポートされる値](/ja/products/customer-data-platform/integration-hub/batch/import/parser/supported-values-for-charset-option-in-csv-parser)を参照してください。 |
| quotes_in_quoted_fields | クォートされたフィールド内の不正なエスケープされていないクォート文字の処理方法を指定します。[ACCEPT_ONLY_RFC4180_ESCAPED](/ja/products/customer-data-platform/integration-hub/batch/import/parser/csv-parser-function#quotes-in-quoted-fields-options)または[ACCEPT_STRAY_QUOTES_ASSUMING_NO_DELIMITERS_IN_FIELDS](/ja/products/customer-data-platform/integration-hub/batch/import/parser/csv-parser-function#quotes-in-quoted-fields-options)のいずれかを指定してください。 |
| columns | 列（以下を参照） |


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

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


## Quotes in Quoted Fieldsオプション

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

| 名前 | 説明 |
|  --- | --- |
| ACCEPT_ONLY_RFC4180_ESCAPED | デフォルト。CSV解析は[RFC 4180](https://www.rfc-editor.org/rfc/rfc4180)に準拠しています。 |
| ACCEPT_STRAY_QUOTES_ASSUMING_NO_DELIMITERS_IN_FIELDS
 | 引用符の間にある迷子のクォートをそのまま受け入れます。引用符の中にデリミタがある場合、動作は未定義です。
例えば、フィールドが "a"b" の場合、中央のクォートは通常の文字として扱われ、結果は **a"b** になります。ただし、フィールドが "a""b" の場合、中央の2つのクォートはエスケープされたクォートと見なされ、結果は **a"b** になります。
 |


## CSVパーサーの設定

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

```yaml
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](/ja/products/customer-data-platform/integration-hub/batch/import/parser/csv-parser-function#csv-parser-use-case-example-1)
* [null_string、trim_if_not_quoted、comment_line_marker、max_quoted_size_limitの使用](<csv-parser-function.md#csv-parser-use-case-example-2)
* [allow_optional_columnsのFALSEとTRUEの効果](/ja/products/customer-data-platform/integration-hub/batch/import/parser/csv-parser-function#csv-parser-use-case-example-3)
* [allow_extra_columnsのFALSEとTRUEの効果](/ja/products/customer-data-platform/integration-hub/batch/import/parser/csv-parser-function#csv-parser-use-case-example-4)
* [クォートおよびエスケープ文字として \0 を使用](/ja/products/customer-data-platform/integration-hub/batch/import/parser/csv-parser-function#csv-parser-use-case-example-5)


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

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

ソースデータの例

```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"
```

```yaml
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データを確認できます。

```bash
$ td connector:preview load.yml
```

データにtime列がない場合は、add_timeフィルターオプションを使用して追加できます。詳細については、[add_timeフィルター関数](/ja/products/customer-data-platform/integration-hub/batch/import/filter/add_time-filter-function)を参照してください。

```bash
$ 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


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

```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 doooooooooooooooooooooooor",18.50,"purple","2016-01-09"
```

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

```yaml
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: {}
```

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

```bash
$ td connector:preview load.yml
```

```bash
+---------+-----------------+--------------+---------------+---------------------------+
| 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に設定した場合の解析結果への影響の例です。

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

```csv
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の設定は以下の通りです。

```yaml
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"の行がありません。

```bash
$ td connector:preview load.yml
```

```bash
+---------+-----------------+--------------+------------+---------------------------+-------------------+
| 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が設定されます。

```bash
+---------+-----------------+--------------+------------+---------------------------+-------------------+
| 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に設定した場合の解析結果への影響の例です。

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

```csv
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の設定は以下の通りです：

```yaml
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"の行のみが表示されます。

```bash
$ td connector:preview load.yml
```

```bash
+---------+----------------+--------------+------------+---------------------------+
| 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"列なしで表示されます。

```bash
$ td connector:preview load.yml
```

```bash
+---------+-----------------+--------------+------------+---------------------------+
| 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` を指定する例です。

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

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

```yaml
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の埋め込みクォートとスラッシュはパーサーに"クォート文字"として指定されていないため、結果に表示されます。


```bash
$ td connector:preview load.yml
```

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