Japanese

embulk-parser-csv_guessable作った

  • このエントリーをはてなブックマークに追加

embulk-parsre-csv_guessableというembulkのプラグインを作りました。

[https://github.com/koooge/embulk-parser-csv_guessable:embed:cite]

これは何?

embulk-standardsのcsvパーサを継承して機能拡張したものです。 オリジナルのcsvパーサでは、csvのスキーマをconfig.ymlにきっちり書く必要があります。 このためスキーマが変更された場合には動的に対応できず、embulkがコケてしまいます。

以前はこの問題に対応するために、embulk runの前にconfig.ymlを生成するオレオレguessスクリプトをかましていました。 が、

これやってしまうとなんでembulk使ってるんだっけ?と思うんですよねえ

— こうげ (@koooge) 2017年4月11日 [https://twitter.com/koooge/status/851758746556551168]という思いから、“Share & reuse the plugin"の精神でpluginを作ってみることにしました。

やりたいこと

下のような1行目がヘッダ行のcsvをよく見ると思います。(なんか名前あるんでしょうか?)

[http://www.soumu.go.jp/toukei_toukatsu/index/seido/9-5.htm:title]

ken-code,sityouson-code,tiiki-code,ken-name,sityouson-name1,sityouson-name2,sityouson-name3,yomigana
1,0,1000,北海道,,,,ほっかいどう
1,100,1100,北海道,札幌市,,,さっぽろし
1,101,1101,北海道,札幌市,,中央区,ちゅうおうく

このヘッダ行を使って、いい感じにパースしたいというのがこのpluginの発想です。

スキーマ変更に柔軟に対応する

オリジナルのcsvパーサだとオレオレスクリプトを噛ましていましたが、embulk-parser-csv_guessableはヘッダ行をカラム名として利用します。

  parser:
    type: csv_guessable
    schema_file: path/to/file_target.csv  # ヘッダのあるファイルを指定する

これによって、カラムの挿入や削除といったスキーマ変更にも対応できるだけでなく、 副次的な効果としてダラダラとcolumnsを定義せずとも簡単に書けます。

カラムの型も指定する

parserでlongなりtimestampなりの型にしておきたいことがあると思います。

型はguessによって(簡単には)どうにもなりそうになかったので、指定したい場合は、元のcsvパーサと同じような書き方ができるようにしました。 なお、string型にする場合は書かなくても良いです。(デフォルトstring)

  parser:
    type: csv_guessable
    schema_file: path/to/file_target.csv
    columns:
      - {name: 'ken-code', type: long}
      - {name: 'sityouson-code', type: long}
      - {name: 'tiiki-code', type: long}

別名にする

特にヘッダが下記のような日本語の場合に、英語名に変更したい事があると思います。

県コード,市町村コード,地域コード,県名,市町村名1,市町村名2,市町村名3,読み仮名
1,0,1000,北海道,,,,ほっかいどう
1,100,1100,北海道,札幌市,,,さっぽろし
1,101,1101,北海道,札幌市,,中央区,ちゅうおうく

古き良きcsvといった感じ。。 下記のような設定で、value_nameをnameに置き換えることができます。

  parser:
    type: csv_guessable
    schema_file: path/to/file_target.csv
    columns:
      - {value_name: '県コード', name: 'ken-code', type: long}
      - {value_name: '市町村コード', 'sityouson-code', type: long}
      - {value_name: '地域コード', name: 'tiiki-code', type: long}
      - {value_name: '県名', name: 'ken-name', type: string}
      - {value_name: '市町村名1', name: 'sityouson-name1', type: string}
      - {value_name: '市町村名2', name: 'sityouson-name2', type: string}
      - {value_name: '市町村名3', name: 'sityouson-name3', type: string}
      - {value_name: '読み仮名', name: 'yomigana', type: string}

parserという割にguessしたりfilterっぽい事もしてるきもしますが、こういうcsvはよくあるので自分的には便利なんですよね。 これらのサンプルをgithubに置いてますのでご覧ください。

今後

イケてない部分がまだありますし、なんかもっと上手い方法がある気がしていますので、もう少しメンテ予定。 お気づきの点をリプライなりPRなりコメントいただけたら幸いです :bow: