今日もプログラミング

IT技術とかプログラミングのこととか特にJavaを中心に書いていきます

EmbulkでMySQLに出力してみる

Embulkでexampleとembulk-plugin-input-randomまで試したので、いよいよMySQLへの出力を試してみる。

ちなみに、実行環境はWindows

 

embulk-output-mysqlプラグインのインストール

MySQLへの出力は、embulk-output-mysqlプラグインが利用できる。

java -jar embulk.jar gem install embulk-output-mysql

おそらく多くのSIerに人は社内プロキシ下にいるので、あらかじめ

set http_proxy=http://<ユーザ名>:<パスワード>@<プロキシサーバ>:<プロキシポート>

みたいにやっておく必要がある。

なお、多くのSIerの人がそうであろうWindows環境の人は、Embulk0.4.6まではJavaプラグインをうまく読み込めないので、0.4.7以降を使う必要がある。

 

MySQLに入れてみる。けどエラー

せっかくexampleがあるので、そいつをMySQLに入れてみようと思う。

ちなみに、exampleのCSVはこんな感じ。

id,account,time,purchase,comment 
1,32864,2015-01-27 19:23:49,20150127,embulk 
2,14824,2015-01-27 19:01:23,20150127,embulk jruby 
3,27559,2015-01-28 02:20:02,20150128,embulk core 
4,11270,2015-01-29 11:54:36,20150129,"Embulk ""csv"" parser plugin"

ローカルのMySQLにこんな風にテーブルを用意して、

create database embulk default character set utf8; 
grant all on embulk.* to embulk_user@'%' identified by 'embulk_pw'; 

use embulk; 

create table example (
  id int,
  account int, 
  time datetime,
  purchase date,
  comment varchar(100)
);

exampleのconfig.ymlをmysql.ymlにコピーし、outputを書き換える。

in:
  type: file
  path_prefix: C:/Test/Embulk/try1/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    escape: ''
    null_string: 'NULL'
    header_line: true
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
exec: {}
out: 
    type: mysql
    host: localhost
    database: embulk
    user: embulk_user
    password: embulk_pw
    table: example
    mode: insert

そして、

java -jar embulk.jar run mysql.yml

を実行。

う…、エラーだ。

2015-02-24 14:58:11.357 +0900 [INFO] (transaction): SQL: CREATE TABLE IF NOT EXISTS `example` (`id` BIGINT, `account` BIGINT, `time` TIMESTAMP, `purchase` TIMESTAMP, `comment` TEXT)
2015-02-24 14:58:11.360 +0900 [INFO] (transaction): > 0.00 seconds
2015-02-24 14:58:11.388 +0900 [INFO] (transaction): {done:  0 / 1, running: 0}
2015-02-24 14:58:11.423 +0900 [INFO] (transaction): {done:  0 / 1, running: 0}
org/embulk/output/jdbc/setter/ColumnSetterFactory.java:133:in `unsupportedOperationException': java.lang.UnsupportedOperationException: Unsupported type INT (sqlType=4, size=10, scale=0)
...

どうも、int型には対応していないらしい。

 

MySQLに入れられた!

ColumnSetterFactoryのソースを見ると、対応しているJDBCのsqlTypeは、数値ではBIGINTのみ、日付ではTIMESTAMPのみのようだ。

ということはdate型もだめか。datetime型のsqlTypeはTIMESTAMPになるので、こっちはOKだ。

文字列型はcharでもvarcharでもOK。

create table example (
	id bigint,
	account bigint,
	time datetime,
	purchase timestamp,
	comment varchar(100)
);

で、成功した!

mysql> select * from example;
+------+---------+---------------------+---------------------+----------------------------+
| id   | account | time                | purchase            | comment          |
+------+---------+---------------------+---------------------+----------------------------+
|    1 |   32864 | 2015-01-28 04:23:49 | 2015-01-27 09:00:00 | embulk          |
|    2 |   14824 | 2015-01-28 04:01:23 | 2015-01-27 09:00:00 | embulk jruby          |
|    3 |   27559 | 2015-01-28 11:20:02 | 2015-01-28 09:00:00 | Embulk "csv" parser plugin |
|    4 |   11270 | 2015-01-29 20:54:36 | 2015-01-29 09:00:00 | NULL          |
+------+---------+---------------------+---------------------+----------------------------+
4 rows in set (0.00 sec)

mysql>

ちなみに、さっきのログを見ると、テーブルが無くても自動的に作るっぽいな。

実際、テーブルを削除して実行しても成功した。

 

まとめ

  • embulk-output-mysqlプラグインで、MySQLに入れられる。
  • Windowsの人はEmbulk0.4.7以降を。
  • 今のところ、数値型はbigint、日付型はdatetimeやtimestamp、文字列型はcharやvarcharなどに対応している。
  • テーブルが無くても自動的に作ってくれる。

 

大量データをロードしてパフォーマンスの検証とかもやってみたい。いずれ。

 

OS Windows 7
Java 8u31
Embulk 0.4.7
MySQL 5.6