Embulkの設定ファイルはliquidというテンプレートエンジンがデフォルトで使えます。
liquidの構文の中に include
というものがあり、liquidファイルから別のliquidファイルを読み込ませることができます。
部分的にパラメータ化できるので便利です。
liquidでincludeで指定したファイルに日本語が含まれているとエラーになったので、その経緯をまとめます。
調査方法
embulk-input-jdbcプラグインを使ってデータを取得する際は下記のような記述をします。
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: |
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