EmbulkでOracleからPostgresへデータ連携（メモ）

# はじめに

お試しで、Embulkを使用してOracleからPostgresへデータ連携させたときのメモです。
特に目新しい情報はないかと思います。
OracleからPostgresへ連携したのは、たまたま手元にこの2つのDBがあったからという理由だけです。

# 環境

- CentOS 7.5(JDK1.8インストール済み）
- Oracle 12cR2
- PostgreSQL 11


# Embulkのインストール

公式サイトのQuick Startを参考にインストールします。

- [Quick Start](https://github.com/embulk/embulk#linux--mac--bsd)

```
curl --create-dirs -o ~/.embulk/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar"
chmod +x ~/.embulk/bin/embulk
echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```


# インポート元（Oracle）のテーブル作成

インポート元（Oracle）のテーブルを以下のように作成します。
レコードも7行ほど入れておきます。

```
CREATE TABLE emp 
 (
 empno VARCHAR2(10),
 area NUMBER(3,0),
 empname VARCHAR2(50),
 insert_time TIMESTAMP(0)
 );

insert into emp values('A1', 1, 'AAAA', current_timestamp);
insert into emp values('A2', 2, 'BBBB', current_timestamp);
insert into emp values('A3', 3, 'CCCC', current_timestamp);
insert into emp values('A4', 4, 'DDDD', current_timestamp);
insert into emp values('A5', 5, 'EEEE', current_timestamp);
insert into emp values('A6', 6, 'FFFF', current_timestamp);
insert into emp values('A7', 7, 'GGGG', current_timestamp);
commit;
```


# インポート先（Postgres）のテーブル作成

インポート先（Postgres）のテーブルを以下のように作成します。
テーブルがない場合、Embulkは自動でテーブルを生成してくれます。
ただし、型が思ったようにならなかったり、インデックスは生成されないため、通常は事前にテーブルを作成しておきます。

```
CREATE TABLE emp 
 (
 empno VARCHAR(10),
 area INTEGER,
 empname VARCHAR(50),
 insert_time TIMESTAMP
 );
```


# プラグインのインストール

今回、プラグインはembulk-input-oracleとembulk-output-postgresqlを使用します。
以下のコマンドでインストールできます。
インストールしたプラグインはデフォルトで「.embulk/lib/gems」以下に格納されます。

```
# embulk gem install embulk-input-oracle
# embulk gem install embulk-output-postgresql
```

embulk-input-oracleとembulk-output-postgresqlの使用方法は以下を参照。

- [embulk-input-oracle](https://github.com/embulk/embulk-input-jdbc/tree/master/embulk-input-oracle)
- [embulk-output-postgresql](https://github.com/embulk/embulk-output-jdbc/tree/master/embulk-output-postgresql)

次に設定ファイル（config.yml）を以下のように作成。
事前にojdbc7.jarをダウンロードし、driver_pathでパスを指定します。

ojdbc7.jarは以下からダウンロードできます。
- https://www.oracle.com/database/technologies/jdbc-drivers-12c-downloads.html

```yml:config.yml
in:
  type: oracle
  driver_path: ./ojdbc7.jar
  host: 192.168.10.232
  user: hr
  password: "hr"
  database: testdb
  table: "emp"
  select: "empno"

out:
  type: postgresql
  host: localhost
  user: postgres
  password: "postgres"
  database: postgres
  table: emp
  mode: insert
```

「embulk preview」コマンドを実行すると、処理されるデータの確認ができます。

```
# embulk preview config.yml
+--------------+-------------+----------------+-------------------------+
| EMPNO:string | AREA:double | EMPNAME:string |   INSERT_TIME:timestamp |
+--------------+-------------+----------------+-------------------------+
|           A1 |         1.0 |           AAAA | 2019-08-27 17:56:54 UTC |
|           A2 |         2.0 |           BBBB | 2019-08-27 17:56:54 UTC |
|           A3 |         3.0 |           CCCC | 2019-08-27 17:56:54 UTC |
|           A4 |         4.0 |           DDDD | 2019-08-27 18:23:57 UTC |
|           A5 |         5.0 |           EEEE | 2019-08-27 18:23:57 UTC |
|           A6 |         6.0 |           FFFF | 2019-08-27 18:24:43 UTC |
|           A7 |         7.0 |           GGGG | 2019-08-27 18:24:43 UTC |
+--------------+-------------+----------------+-------------------------+
```

「embulk preview」コマンドでの確認結果が問題なかったら、「embulk run」でデータ連携を実行します。

```
# embulk run config.yml
```


# CSVに出力する場合（おまけ）

出力先（out）を以下のように記述すると、「file/users.csv」以下にCSVファイルで出力されます。

```yml:config.yml
out:
  type: file
  path_prefix: "./file/users"
  sequence_format: "."
  file_ext: csv
  formatter:
    type: csv
    delimiter: ","
    newline: CRLF
    newline_in_field: LF
    charset: UTF-8
    quote_policy: MINIMAL
    quote: '"'
    escape: "\\"
    null_string: "\\N"
    default_timezone: 'Asia/Tokyo'
```


# 設定を外だしする

Oracleのユーザ名、パスワードなどは別ファイルに定義するように変更します。
以下の2ファイルを作成します。

config_ora_csv.yml.liquid: メインの設定ファイル
_env.yml.liquid: ユーザ名、パスワードなどの設定ファイル

それぞれのファイルは以下のように記載します。

```yaml:config_ora_csv.yml.liquid
{% include 'env' %}
in:
  type: oracle
  driver_path: ./ojdbc7.jar
  host: {{ ora_host }}
  user: {{ ora_user }}
  password: {{ ora_password }}
  database: {{ ora_database }}
  table: emtest
  select: "*"
※out:は省略
```

```yaml:_env.yml.liquid
{% assign ora_host = '192.168.10.232' %}
{% assign ora_user = 'hr' %}
{% assign ora_password = 'hr' %}
{% assign ora_database = 'testdb' %}
```

ポイントは以下のとおり。

- ファイル名に.liquidを追加
- includeで別ファイルを読み込む。envをincludeしたら、ファイル名は"_env.yml.liquid"とする。

実行結果は以下のようになります。

```
# embulk run config_ora_csv.yml.liquid
# cat ./file/emtest.csv
NO,NAME,UPDATE_AT
2.0,BBBB,2019-09-02 00:14:40.000000 +0900
3.0,CCCC,2019-09-02 00:14:46.000000 +0900
4.0,CCCC,2019-09-02 00:16:52.000000 +0900
```


# 参考

- [Embulkについてまとめてみた　2017/08](https://qiita.com/tashiro_gaku/items/f7fa0f1a99c759d947a7)
- [Embulkのコマンドヘルプまとめ](https://qiita.com/hiroysato/items/86ad1cdfb1754440eed5)
- [embulk-input-oracle](https://github.com/embulk/embulk-input-jdbc/tree/master/embulk-input-oracle)
- [embulk-output-postgresql](https://github.com/embulk/embulk-output-jdbc/tree/master/embulk-output-postgresql)