もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

embulkためす

はじめに

こんばんは

こちらの記事はユアマイスターアドベントカレンダー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":{}}

成功しました!

f:id:kojirooooocks:20201210043205p:plain

BigQueryにも保存されています!

ちなみに、コピー元のmysqlスキーマが変更された場合、 mode: append になっていると実行時にスキーマが違うことでエラーが発生します。

mode: replace になっていれば、 コピー元のスキーマが変更されても 変更してくれるみたいです。

終わりに

こんな感じでとても簡単にできました。

embulk楽しいですね。

もうちょい素振りしておこうと思います。

また、ユアマイスターではエンジニアを積極採用中です。

ご興味がある方はご連絡ください。

corp.yourmystar.jp