きっかけ
embulk で mysql にLivedoorグルメDatasetを入れてたときにふと思いました。
column名にtypeがついてたら Elasticsearch や Solr の DynamicField に使いやすんじゃないかと。
rename filter ではできなそうで、twitterにポロッと書いたら助言を頂いて、plugin書いてみようかなと思った次第です。
普段はbash書いたり、ちょこっとPythonを書くくらいですが、たしかに書けそうな気がするなー、文字列連結するだけだもんなー、と思ったのでやってみることにしました。rubyはchefでちょっとだけ書いたことがある程度です。
embulk plugin を作ってみる
設計
column | type | output |
---|---|---|
name | string | name_s とか s_name とか |
id | long | id_l とか l_id とか |
プラグインテンプレートを作る
$ embulk new ruby-filter affix
$ tree embulk-filter-affix/
embulk-filter-affix/
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── embulk-filter-affix.gemspec
└── lib
└── embulk
└── filter
└── affix.rb
3 directories, 6 files
$
動作確認できるようにしておく
- restaurants.csv: Livedoorグルメデータセットのレストラン情報
- seed.yml: embulk guess で使うやつ
in:
type: file
path_prefix: restaurants.csv
filters:
- type: affix
affix: prefix
out:
type: stdout
filters はこんなふうに使えたらいいかな、という希望で書いてみた。
$ embulk guess seed.yml
で確認して
$ embulk guess seed.yml -o config.yml
で config.ymlを出力
試しにembulk preview
試しにpreviewしてみようとすると
$ embulk preview config.yml -L embulk-filter-affix -G
(略)
Error: Required field "option1" is not set
$
embulk-filter-affix/lib/embulk/filter/affix.rb を見ると option1 が integer で required みたいなので
(略)
filters:
- type: affix
affix: prefix
option1: 10
(略)
こんな感じにして再実行してみると
$ embulk preview config.yml -L embulk-filter-affix -G
(省略)
*************************** 60 ***************************
(省略)
example ( string) : example
column ( long) : 1
value ( double) : 1.0
csvに無いカラムが3つ追加され、とりあえずサンプルは動くことが確認できる。
本題:column名のprefixやsuffixにtypeをつけてたい
code
module Embulk
module Filter
class Affix < FilterPlugin
Plugin.register_filter("affix", self)
def self.transaction(config, in_schema, &control)
task = {
"affix" => config.param("affix", :string, default: "suffix"),
}
columns = []
in_schema.each do |record|
if task['affix'] == "suffix" then
name = record.name + "_" + record.type.to_s[0]
elsif task['affix'] == "prefix" then
name = record.type.to_s[0] + "_" + record.name
else
name = record.name
end
column = Column.new(nil, name, record.type)
columns.push(column)
end
out_columns = columns
yield(task, out_columns)
end
def init
# initialization code:
@affix = task["affix"]
end
def close
end
def add(page)
page.each do |record|
page_builder.add(record)
end
end
def finish
page_builder.finish
end
end
end
end
実行結果
(略)
filters:
- type: affix
affix: suffix
(略)
だと
$ embulk preview config.yml -L embulk-filter-affix -G
(略)
*************************** 62 ***************************
id_l ( long) : 65
name_s ( string) : 備長
(略)
access_count_l ( long) : 2,370
created_on_t (timestamp) : 2000-09-10 11:22:02 UTC
modified_on_t (timestamp) : 2011-04-21 12:00:19 UTC
closed_l ( long) : 0
(略)
filters:
- type: affix
affix: prefix
(略)
だと
$ embulk preview config.yml -L embulk-filter-affix -G
(略)
*************************** 62 ***************************
l_id ( long) : 65
s_name ( string) : 備長
(略)
t_created_on (timestamp) : 2000-09-10 11:22:02 UTC
t_modified_on (timestamp) : 2011-04-21 12:00:19 UTC
l_closed ( long) : 0
できたー!
gem を作る
$ cd embulk-filter-affix
$ rbenv install jruby-9.1.5.0
$ rbenv exec gem install bundler
$ bundle install
$ rake
embulk-filter-affix 0.1.0 built to pkg/embulk-filter-affix-0.1.0.gem.
$
とりあえずのgithub
公開してみる
gemspec 修正
gemspecファイルを修正する。
$ git diff embulk-filter-affix.gemspec
diff --git a/embulk-filter-affix.gemspec b/embulk-filter-affix.gemspec
index 11d2dfe..e8c8c5e 100644
--- a/embulk-filter-affix.gemspec
+++ b/embulk-filter-affix.gemspec
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
spec.description = "Affix"
spec.email = ["imura81gt@gmail.com"]
spec.licenses = ["MIT"]
- # TODO set this: spec.homepage = "https://github.com/imura81gt/embulk-filter-affix"
+ spec.homepage = "https://github.com/imura81gt/embulk-filter-affix"
spec.files = `git ls-files`.split("\n") + Dir["classpath/*.jar"]
spec.test_files = spec.files.grep(%r{^(test|spec)/})
$
git commit しておく。
rubygems.org にアカウントを作っておく。
$ gem push
で認証情報を入れておく。
リリース!!!!!!!!!
$ rake release
embulk-filter-affix 0.1.0 built to pkg/embulk-filter-affix-0.1.0.gem.
Tag v0.1.0 has already been created.
Pushed embulk-filter-affix 0.1.0 to rubygems.org.
$
$ embulk gem search embulk-filter-affix
2017-04-09 10:59:20.013 +0900: Embulk v0.8.17
*** REMOTE GEMS ***
embulk-filter-affix (0.1.0)
$
Customization — Embulk 0.8 documentation
http://www.embulk.org/docs/customization.html#creating-plugins