DataSpider（Dr.Sum Connect）をつかったETLのスクリプトのつくり方

# 最初に
### Dr.Sum とは

https://www.wingarc.com/product/dr_sum/

https://www.wingarc.com/product/dr_sum/ds20th-anniversary/index.html

<details><summary>【詳細はこちら】**Dr.Sum**は10億件のデータを1秒台で集計できる超高速データベースツールです。</summary><div>
高速のディスク集計と、ハイブリッドで使える超高速のメモリ集計をつかいながら、最適な運用コストでのパフォーマンスを実現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/e8924330-f537-38f2-e276-ecdd0d96341d.png)

また、Dr.Sumは集計速度だけでなく、データベース構築経験の少ない方でもGUI操作でDBをつくったり、データを取り込んだりできます。
データベース周りにそこまで強くないぼくのような人間でも、気軽にデータハンドリングができるところが素敵です。

さて、Dr.Sumという製品は単純にデータベースがあるだけではなく、様々なオプション製品を加えることで、多様な使い方が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/12be6f13-7354-f58a-773c-b43934d30666.png)

詳しくは公式ホームページをご参照いただきたいのですが、
✅ データを抜いて
✅ データを加工して
✅ データを貯めて
✅ データを高速集計する
ことが可能となります。

[製品の一覧はこちら](https://www.wingarc.com/product/dr_sum/lineup/index.html)

</div></details>


### Dr.Sum Connect とは

https://www.wingarc.com/product/dr_sum/lineup/connect.html

<details><summary>【詳細はこちら】**Dr.Sum Connect**はデータを抽出・加工・取り込みをするETLツールです。</summary><div>


下図のように様々な環境からデータを取得して、加工して、Dr.Sumに投げ込むことのできるツールです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/f7ac2d53-4b95-063c-27af-2fe4a07da4de.png)

エラーになったらログを吐いたり、メールを飛ばしたり、だいたいGUIで操作できるので、プログラムを書かずとも連携の仕組みを作ることができます。

基本的なスクリプトのつくり方についてはこちらの解説記事をお読みください。
[Dr.Sum ConnectをつかったETLのスクリプトのつくり方](https://qiita.com/Ryo---san/items/5c952ed15a6adb576547)

</div></details>

Dr.Sum ConnectはDataSpiderのOEM製品です。
以降の記事ではConnectと書きます。

Connectがあるとデータの連携作業がとてもお手軽になります。プログラムを書く必要がほぼなくなりますからね。
しかしいくら簡単に処理ができると言っても、ひとつの画面（スクリプト）にたくさんコンポーネントを置いてしまうと、訳が分からなくなり、属人化して他の人に引き継ぎがしにくくなってしまうという弊害が出てきます。

ぜひともスクリプトの正しいを覚えてみましょう。



# スクリプトのつくり方
## 親子関係を意識する
プログラム開発をする方なら意識されると思うのですが、スクリプトが冗長化させない秘訣は、スクリプトを分割することです。
その内の最適な分割方法というのは
・ログ出力、メール送信などの決まった処理はスクリプト化
・１つのテーブルの抽出→加工→取り込みまでを１スクリプトにする
という点です。

最初に作り込むときから、スクリプトをどう分割するかを頭の中に入れておくと、可読性の高いスクリプトがつくれます。
規模が大きくなってくると親・子・孫・ひ孫・玄孫（やしゃご）くらいまでは登場しますwww

各スクリプトの親子関係はこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/6d1578ea-4651-4f51-3562-2e88247017a3.png)

## なぜ親子関係にするかをもう少し解説
先ほどもちょっと記載しましたが、大きなメリットは２つあるかなと思います。

### 可読性の向上による属人化の解消
ぱっと見、わかりやすいんですね。
このジョブはなんのために動いている、次は何をする処理だなど、見てすぐにわかります。
そして例えば「売上テーブルの加工ってどうやってたっけ？」となると、すぐに販売管理の売上スクリプトを覗きに行くことができます。

この可読性の高さは、担当が突然いなくなったり（考えたくないですが）しても、引き継ぐことができます。

ちなみに大半のETLツールは仕様書の出力機能もついていて、HTMLに記載されるので、細かな処理は仕様書から追うこともできます。


### エラーハンドリングが容易
これもポイント高いです。
ETL関連の大事なポイントは障害発生時にいかに脳を殺して、短時間で復旧できるかにかかっています。
障害が発生すると、基本的にバタバタします。平常心ではいられません。
そのときに可読性が悪いロジックだったり、復旧手順が複雑だと、二次被害を巻き起こしてしまうことがあるのです。

理想の形はエラーになった箇所をログから特定し、**もう一度そこから流してあげる**と処理がうまく行くように作り込むことです。
あれやこれやと処理を組み替えていると、**人間いつかはミスをします。**
特に夜中に異常終了となり、朝までに復旧しないとならない状況とかだと、**ホントミスします。**
なのでエラー時のハンドリングを常に意識して作り込みましょう。

## Insertオンリーはオススメできない。
次のスクリプトのつくり方のコツですが、なるべくならデータベースへの単純Insertはやめましょう。
これも理由はエラーハンドリングです。

データ元が変わらない限り、何度処理を流しても、**取り込んだデータは増減しない**ようにつくることが理想です。

Insertオンリーですと、処理を流すたびにデータが増えていきます。
ユニークキーが設定されていたら、エラーとなりますが、そのジョブは毎回エラーとなり、障害発生時には邪魔な存在となります。

こうしたことを防ぐために、
✅ 可能であれば、移行先のテーブルは全件削除→挿入
✅ 差分取り込みならば、移行先のテーブルの対象の期間のデータを削除→対象の期間のデータだけ挿入

という形になるようにしましょう。

# 実際のスクリプトで解説
それでは上記を意識した、スクリプトを紹介します。


### DailyBatch
親スクリプトであるDailyBatchです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/90d5d18b-986d-a2d8-667a-63f339bdf791.png)

このスクリプトをトリガーに仕込んで、毎日決まった時間にデータが流れます。
コンポーネントのほとんどは、子スクリプトを呼び出しているものです。

### 臨時バッチ
なお、ほぼ同じ形の臨時バッチというものもつくっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/91527c3e-d057-7a26-e72e-65ee52aa4122.png)

こちらはエラー復旧用で、エラーになった箇所から再実行するためのものです。


###子スクリプトのひとつ
実行のメインとなる子スクリプトのひとつです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/b52413e6-656f-6edd-7245-677a436900f7.png)

連続してデータを取り込もうとしています。
さらにここから孫スクリプトを呼び出しています。
孫スクリプトのひとつひとつが実際に、テーブルを抽出・加工・取り込み処理をしているところです。

### 孫スクリプトのひとつ
ここではSalesforceのひとつのオブジェクトからデータを抜き、マッピングをしてDr.Sumに取り込んでいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/95ab99d8-3455-e7fb-6b7c-3f97df53d59d.png)

キーポイントはtruncate_table_dataのところですね。
Dr.Sumのテーブルを全件削除しているのです。
ここの削除条件が複雑だったり、Insertするデータが差分であると、ロジックが複雑化し、エラーハンドリングの難易度が高まります。


### 実行ログスクリプト
これから何かをするときに、必ず呼び出されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/d16c4b2e-9c94-47f4-b9de-4965cee8b888.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/d2e97b15-4673-03b5-6074-2c9237969081.png)

単純明快ですね。
でもわざとスクリプト化しています。
もし文言を変えたくなったときに、ひとつ一括で変更されますので、メンテナンス性が向上します。
同様にエラーログスクリプトも存在します。

### 管理者メールスクリプト
異常終了の時は、キチンと管理者にメールを飛ばしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/3a9b9365-a15a-4f42-b909-c7e35538af05.png)

どの部分でコケたかを教えてあげると、障害対応者の心的ストレスの軽減につながります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/c100c043-547a-63ea-b83f-d17593ba97b5.png)


これらの基本的なスクリプト構成を意識していると、どのETLツールにも対応できるようになります。
実際に、ぼくも4つくらいETLツールを扱えますが、基本構成はどこも似たようなものです。

# おわりに
いかがだったでそうか。

最初は少々めんどうでも、一度この構成でつくってしまえば、今後の運用のハードルはとっても下がります。
開発する時間は瞬間的ですが、運用は永続です。

ストレスのない運用を意識したスクリプト管理をしてみませんか？