7
4

More than 5 years have passed since last update.

Embulkでliquidテンプレート内でincludeするときの注意点

Last updated at Posted at 2019-06-02

Embulkの設定ファイルはliquidというテンプレートエンジンがデフォルトで使えます。

liquidの構文の中に includeというものがあり、liquidファイルから別のliquidファイルを読み込ませることができます。
部分的にパラメータ化できるので便利です。

liquidでincludeで指定したファイルに日本語が含まれているとエラーになったので、その経緯をまとめます。

調査方法

embulk-input-jdbcプラグインを使ってデータを取得する際は下記のような記述をします。

sample.yml.liquid
in:
  type: jdbc
  url: your_url
  user: your_user
  password: your_password
  driver_path: /yourdriver.jar
  driver_class: org.your.Driver
{% include 'query_template' %}

out:
  type: stdout
query_template.yml.liquid
  query: |
    SELECT id, name FROM Items WHERE name like '%好きなもの%'

これをembulk runを実行するとエラーになります。

org.embulk.exec.PartialExecutionException: org.embulk.config.ConfigException: 'table' or 'query' parameter is required
    at org.embulk.exec.BulkLoader$LoaderState.buildPartialExecuteException(BulkLoader.java:340)...

queryのパラメータが指定されてないというエラーです。
includeのパスは正しいので、includeの処理が何かおかしいです。

embulk guessで設定ファイルがどうなっているか見てみます。

in:
  type: jdbc
  url: your_url
  user: your_user
  password: your_password
  driver_path: /yourdriver.jar
  driver_class: org.your.Driver
Liquid error: internal

out:
  type: stdout

internal エラーと表示されました。これは確かにqueryというパラメータは指定されてないですね。
しかしこの情報では原因は良くわからない。

queryの中身を変えて試した結果 日本語の有無 によってエラーが発生することがわかりました。
ちょっと調べにくいですね。

そもそもEmblukの設定ファイルに日本語が含まれていると文字化けしてしまうので、うまく扱うことができません。たまたまincludeの中で使ってしまったために原因が掴みにくく詰まってしまいました。

回避策

苦肉の策ですがViewを使ってクエリの中身を隠蔽し、日本語を記述しないことで回避できます。そもそも日本語を適切に扱う方法があれば一番いいのですが、何か方法があれば知りたいです。

2019-06-16 14:52 追記

@hiroysato さんにコメントいただき原因と対策が分かりましたので追記します。調査していただきありがとうございました。

問題の再現や、解決方法のサンプルスクリプトは下記に置いてあります。
https://github.com/tyubo/embulk-jp-test

原因

この記事で紹介したEmbulkの処理はdockerを使って実現していました。
そこにjavaの公式imageを使っていましたが、デフォルトの状態ではlocaleの設定が不十分で下記のような警告が出ていました。

locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory

この状態でEmbulkを実行すると file.encoding = ANSI_X3.4-1968 で動作することになり、UTF-8で記述された日本語を使うことができないようです。

そこでEmbulkを動作させるDockerfileを下記のように記述することで解消できました。(@hiroysato さんに助言いただきました)
https://github.com/tyubo/embulk-jp-test/blob/master/with_digdag_mod/Dockerfile

FROM java:8-jre

RUN apt-get update && \
    apt-get -y install openssh-client

RUN sed -i '/jessie-updates/d' /etc/apt/sources.list &&\
    rm -f /etc/apt/sources.list.d/jessie-backports.list &&\
    cat /etc/apt/sources.list &&\
    apt-get update -qq &&\
    apt-get install -y locales

RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8"

RUN curl -o /bin/embulk -L "https://dl.bintray.com/embulk/maven/embulk-0.9.5.jar" && \
    chmod +x /bin/embulk

RUN mkdir -p /var/lib/embulk
WORKDIR /var/lib/embulk

COPY Gemfile .
COPY Gemfile.lock .

RUN embulk bundle install --path vendor/bundle
7
4
11

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4