はじめに
こんばんは
こちらの記事はユアマイスターアドベントカレンダー2020の10日目の記事です。
先日、次の自分のチケットアサインMTGで、 embulkを使うような仕事が来る可能性がありそうでした。
embulkは3〜4年前に個人的に少しだけ触った記憶しかないので、もし来たとき用に素振りしようと思います。
本題
前提
今回はこのデータで試します。
example_db
mysql> show tables; +----------------------+ | Tables_in_example_db | +----------------------+ | users | +----------------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM users; +----+-------+---------------------+---------------------+ | id | name | created | modified | +----+-------+---------------------+---------------------+ | 1 | test | 2020-12-01 00:00:00 | 2020-12-01 00:00:00 | | 2 | test2 | 2020-12-01 00:00:00 | 2020-12-01 00:00:00 | | 3 | test3 | 2020-12-01 00:00:00 | 2020-12-01 00:00:00 | | 4 | test3 | 2020-12-01 00:00:00 | 2020-12-01 00:00:00 | | 5 | test4 | 2020-12-01 00:00:00 | 2020-12-01 00:00:00 | +----+-------+---------------------+---------------------+ 5 rows in set (0.00 sec)
example_db_2
mysql> show tables; Empty set (0.00 sec)
example_db には users というテーブルがあり、データが入っています。
example_db_2 にはテーブル自体が存在しません。
in: mysql, out: mysqlで試してみる
1. 本体のインストール
$ brew install embulk $ embulk --version embulk 0.9.23
2. プラグインのインストール
今回は試しに、in, outともにmysqlにしてみます。
$ embulk gem install embulk-input-mysql $ embulk gem install embulk-output-mysql
3. 設定ファイル
_env.yml.liquid
{% assign in_host = '127.0.0.1' %}
{% assign in_user = 'kojirock' %}
{% assign in_password = '1qaz2wsx' %}
{% assign in_database = 'example_db' %}
{% assign out_host = '127.0.0.1' %}
{% assign out_user = 'kojirock' %}
{% assign out_password = '1qaz2wsx' %}
{% assign out_database = 'example_db_2' %}
users.yml.liquid
{% include 'env' %}
in:
type: mysql
host: {{ in_host }}
user: {{ in_user }}
password: {{ in_password }}
database: {{ in_database }}
table: users
select: "id, name"
out:
mode: replace
type: mysql
host: {{ out_host }}
user: {{ out_user }}
password: {{ out_password }}
database: {{ out_database }}
table: users
select: "id, name"
4. 実行
一旦 previewで実行してみます。
$ embulk preview users.yml.liquid ... 2020-12-10 02:46:52.550 +0900 [INFO] (0001:preview): SQL: SELECT id, name FROM `users` 2020-12-10 02:46:52.552 +0900 [INFO] (0001:preview): > 0.00 seconds +---------+-------------+ | id:long | name:string | +---------+-------------+ | 1 | test | | 2 | test2 | | 3 | test3 | | 4 | test3 | | 5 | test4 | +---------+-------------+
良さげなので、実行してみます。
$ embulk run users.yml.liquid
...
2020-12-10 02:47:55.849 +0900 [INFO] (main): Committed.
2020-12-10 02:47:55.849 +0900 [INFO] (main): Next config diff: {"in":{},"out":{}}
成功したので、mysqlを見てみます。
$ mysql -u kojirock -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 114 Server version: 8.0.22 Homebrew Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use example_db_2 Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +------------------------+ | Tables_in_example_db_2 | +------------------------+ | users | +------------------------+ 1 row in set (0.00 sec) mysql> select * from users; +------+-------+ | id | name | +------+-------+ | 1 | test | | 2 | test2 | | 3 | test3 | | 4 | test3 | | 5 | test4 | +------+-------+ 5 rows in set (0.00 sec)
example_db_2に移すことが出来ました!!
これがだいたい基本の動きなのかな?
in: mysql, out: bigQueryで試してみる
1. プラグインのインストール
$ embulk gem install embulk-output-bigquery
3. 設定ファイル
_env.yml.liquid
{% assign in_host = '127.0.0.1' %}
{% assign in_user = 'kojirock' %}
{% assign in_password = '1qaz2wsx' %}
{% assign in_database = 'example_db' %}
{% assign out_json = '/path/to/kojirock-bigquery.json' %}
{% assign out_project = 'example_project' %}
{% assign dataset = 'dataset_example1' %}
users.yml.liquid
{% include 'env' %}
in:
type: mysql
host: {{ in_host }}
user: {{ in_user }}
password: {{ in_password }}
database: {{ in_database }}
table: users
select: "id, name"
out:
type: bigquery
mode: replace
table: users
select: "id, name"
auth_method: json_key
json_keyfile: {{ out_json }}
project: {{ out_project }}
dataset: {{ dataset }}
location: asia-northeast1
compression: GZIP
auto_create_table: true
4. 実行
一旦 previewで実行してみます。
$ embulk preview users.yml.liquid 2020-12-10 04:12:26.448 +0900: Embulk v0.9.23 ... 2020-12-10 04:12:29.209 +0900 [INFO] (0001:preview): SQL: SELECT id, name FROM `users` 2020-12-10 04:12:29.211 +0900 [INFO] (0001:preview): > 0.00 seconds +---------+-------------+ | id:long | name:string | +---------+-------------+ | 1 | test | | 2 | test2 | | 3 | test3 | | 4 | test3 | | 5 | test4 | +---------+-------------+
良さげなので、実行してみます。
$ embulk run users.yml.liquid
2020-12-10 04:12:34.929 +0900: Embulk v0.9.23
...
2020-12-10 04:17:04.085 +0900 [INFO] (main): Committed.
2020-12-10 04:17:04.086 +0900 [INFO] (main): Next config diff: {"in":{},"out":{}}
成功しました!

BigQueryにも保存されています!
ちなみに、コピー元のmysqlのスキーマが変更された場合、 mode: append になっていると実行時にスキーマが違うことでエラーが発生します。
mode: replace になっていれば、 コピー元のスキーマが変更されても 変更してくれるみたいです。
終わりに
こんな感じでとても簡単にできました。
embulk楽しいですね。
もうちょい素振りしておこうと思います。
また、ユアマイスターではエンジニアを積極採用中です。
ご興味がある方はご連絡ください。