Liquid
Liquid の公式サイトはこちらです。
Embulk
Embulk の公式サイトはこちらです。この記事では Embulk そのものについては扱いません。
Embulk の設定ファイルとして Liquid を用いる
Embulk の設定ファイルは YAML で書かれます。加えて、「YAML を include 可能にした拡張形式である*1 Liquid という形式」にも対応しています。
ここでは Liquid を用いて Embulk の設定ファイルをどのように書けばいいのかを記していきます。
原則
まず原則をいくつか書き連ねます。
- Liquid ファイルの中身の書式は YAML そのものである
- Liquid ファイルは多段に include することはできない*2
- したがって設定ファイル群の構成は次のとおりになる
- 「全ての Liquid ファイルが include される親ファイル(include 先となるファイル)」が一つある
- 上記のファイル以外は include されるファイル(子ファイル)になる
- 「親ファイル」も「子ファイル」も Liquid ファイルである
- Liquid ファイルの拡張子は
.yml.liquid
である- つまり全てのファイルの拡張子は
.yml.liquid
である
- つまり全てのファイルの拡張子は
- 「子ファイル」のファイル名の先頭には
_
(アンダーバー、アンダースコア)を付与する- 「親ファイル」のファイル名には命名規則はない
- 「子ファイル」の場所はサブディレクトリ内でもよい
- include の際に指定すればよい
- ただし自分より下位のディレクトリでなければいけない*3
include するときの規則
Liquid ファイルを include する際の規則は次のとおりです。
- include したいファイル名*4を
{%
と%}
で囲む- ただし、囲まれるファイル名は以下の規則に従う
- 拡張子*5は省略する
- ファイル名の先頭の
_
(アンダーバー、アンダースコア)は省略する
- ただし、囲まれるファイル名は以下の規則に従う
- include 命令を記述する際は YAML のインデントに則って記載する*6
具体例
上記までの内容を踏まえ、具体的な例を見ていきます。
「親ファイル」の内容
まず、全てのファイルのファイル名が以下のとおりであるとします。
parent.yml.liquid
_input.yml.liquid
_diff.yml.liquid
_output.yml.liquid
parent.yml.liquid
が「親ファイル」で、それ以外のファイルは parent.yml.liquid
に include されます。したがって、parent.yml.liquid
の内容は以下のようになります。
{% include 'input' %} {% include 'diff' %} {% include 'output' %} table: my_table
ここで、{% include 'diff' %}
はインデントをした上で include されていることと、「table: my_table」という項目が直書きで追加されていることは大切なところです。
{% include 'input' %}
と {% include 'diff' %}
の内容
{% include 'input' %}
と {% include 'diff' %}
の部分を見てみます。それぞれのファイルの中身は次のとおりです。
_input.yml.liquid
in: type: file path_prefix: this_is_prefix_ file_ext: csv parser: stop_on_invalid_record: true charset: UTF-8 newline: LF type: csv delimiter: ',' quote: '"' escape: '"' skip_header_lines: 1 columns: - {name: id, type: long} - {name: name, type: string} - {name: age, type: long} - {name: birth_day, type: timestamp, format: '%Y-%m-%d'}
_diff.yml.liquid
_diff.yml.liquid
の中身を見てみます。このファイルは -c
オプションによって生成されるものを想定しています
一行だけなので分かりづらいですが、冒頭に半角スペースが 2つ 空いています(インデントされています)。
last_row: 12345
さて、_input.yml.liquid
と _diff.yml.liquid
の二つのファイルがもし YAML に直書きされていたとすると、以下のようになります。_diff.yml.liquid
がインデントされて(冒頭に半角スペースが 2つ 空けて)書かれていたことが、統合結果にそのまま反映されることがポイントです。
in: type: file path_prefix: this_is_prefix_ file_ext: csv parser: stop_on_invalid_record: true charset: UTF-8 newline: LF type: csv delimiter: ',' quote: '"' escape: '"' skip_header_lines: 1 columns: - {name: id, type: long} - {name: name, type: string} - {name: age, type: long} - {name: birth_day, type: timestamp, format: '%Y-%m-%d'} last_row: 12345
{% include 'output' %}
の内容と table: my_table
の部分
{% include 'output' %}
の中身は次のとおりです。
_output.yml.liquid
out: type: mysql host: 192.168.0.1 port: 3306 user: username password: password database: db_name mode: merge
「親ファイル」に直書きしている記述がある
「親ファイル」である parent.yml.liquid
には、{% include 'output' %}
の記述の下に、インデントをした上で table: my_table
という直書きした記述があります。
この場合は直書きした内容がそのまま反映されます。繰り返しますが、インデントに注意して下さい。{% include 'output' %}
の include と、table: my_table
の直書きとを併せた記述は以下の記述と同じになります。
out: type: mysql host: 192.168.0.1 port: 3306 user: username password: password database: db_name mode: merge table: my_table
全ての Liquid ファイルが include された内容
上記までの内容に従い、4つの Liquid ファイルを併せたファイルの内容は、以下の内容(YAMLファイル)になります。
in: type: file path_prefix: this_is_prefix_ file_ext: csv parser: stop_on_invalid_record: true charset: UTF-8 newline: LF type: csv delimiter: ',' quote: '"' escape: '"' skip_header_lines: 1 columns: - {name: id, type: long} - {name: name, type: string} - {name: age, type: long} - {name: birth_day, type: timestamp, format: '%Y-%m-%d'} last_row: 12345 out: type: mysql host: 192.168.0.1 port: 3306 user: username password: password database: db_name mode: merge table: my_table
Liquid をうまく使って DRY に設定ファイルを書く
これで Liquid を用いて Embulk の設定ファイルを書けるようになりました。Liquid ファイルの内容を任意の場所に「挟み込める」ようになったわけです。
Embulk を本格的に使い始めると、同じ記述や似たような記述が各所で発生すると思います。その際は Liquid をうまく使って DRY なコード構成にしたいですね。