既存のデータをクソ簡単にAzure DataFactory で取り込んでみる

今日は、次のハックで使用する Azure DataFactory を触ってみた。基本的にチュートリアルと同じ構成だが、さらっと流されている部分もすべて検証してみた。

![DataFactory.png](https://qiita-image-store.s3.amazonaws.com/0/3470/9498a8b1-ff30-134f-350c-d33a496130a8.png)

Azure Factory は、クラウドベースのデータ統合サービスで、データドリブンワークフローをクラウド上でオーケースとレーションしたり、データの移動を自動化してくれるものだ。

様々なデータソースから、データを抽出して、データソースに同期したり、移行してくれたりする。

基本的に(Tutorial: Create a pipeline with Copy Activity using Data Factory Copy Wizard)[https://docs.microsoft.com/en-us/azure/data-factory/data-factory-copy-data-wizard-tutorial]の手順を流している。

# 事前準備

チュートリアルにあるように、Storage Account を作成し、SQL database を Azure 上に作成済みである。
また、テーブルも作成済み。テーブル作成は、Visual Studio で実施した。

```sql
CREATE TABLE [dbo].[emp] (
    [ID]        INT          IDENTITY (1, 1) NOT NULL,
    [FirstName] VARCHAR (50) NULL,
    [LastName]  VARCHAR (50) NULL
);


GO
CREATE CLUSTERED INDEX [IX_emp_ID]
    ON [dbo].[emp]([ID] ASC);
```

私は、SQL データベースにはあまり慣れていない。ちなみに、クラスタード/非クラスタードインデックスが存在する。クラスタードは、主キーなどに使われるもので、ソートされて格納されるタイプであり、テーブルに１つしかもてない。非クラスターは、いくつも持てるが、B-Tree インデックスタイプ格納方法をとられている。O(logN) のオーダーで検索できるタイプ。

[Clustered and Nonclustered Indexes Described](https://docs.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described)

さて、テーブルが晴れたら、Data Factory で、アクションを作っていこう。

# データのストレージへの格納

今回は次のようなテキストデータが存在する。

```
John, Doe
Jane, Doe
```
こいつが emp.txt に格納されている。これを、Storage Account のBlob Storage にアップしておく。
ちなみに、Azure のBlob Storage の操作には、[Micirosoft Azure Storage Explorer](http://storageexplorer.com/)がある。Linux や Mac 向けもある。こいつをつかって、テキストファイルをアップロードする。ここで、ついでに、zip 圧縮して、emp.zip もつくってあげておく。

![StorageExplorer.png](https://qiita-image-store.s3.amazonaws.com/0/3470/c2a2e7fb-bc46-f84b-debe-ed41b0c77ae6.png)

# Azure Data Factory のコンフィグレーション

## Azure DataFactory での Copy Data の実行

今回は、様々な方法があるが、まずは簡単そうな Copy Data を使ってみる。ほかにも Portal からする方法、PowerShell や C# で実装する方法、ARM を使う方法などがあるようだ。

![Top.png](https://qiita-image-store.s3.amazonaws.com/0/3470/27fa16e3-1c8e-feb5-23a3-4ab283c66e74.png)

## Task のコンフィグレーション

ここでは、タスクを定義している。１回だけの移行と、一定期間同期するような方法が選択できる。ここでは、同期する方法を選んで、開始日を過去日付に、終了日を本日の遅めの時間にしている。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/3470/49efb0fc-dfb5-f6b1-88a2-18567e204618.png)

## データソースの指定

データの取得元。今回は Storage Account なのでそれを指定する。様々なデータソースからデータを取得できる。どのようなデータソースが使えるかは[Data movement activities](https://docs.microsoft.com/en-us/azure/data-factory/data-factory-introduction)にのっている。Azure以外にも、Amazon Redshift, S3, Oracle, SAP, Sybase, Teradata など様々なデータソースから取り込める。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/3470/7d9b7417-f4c6-aa57-dc2a-697cd8c69c68.png)

## Storage Account の設定

ここでは、先に作った Storage Account を指定している。

![003.png](https://qiita-image-store.s3.amazonaws.com/0/3470/424bdf58-353d-7ce2-ad55-e2a47f0cd413.png)

## データの取り込み 

そして、ファイルを選択できる。普通のプレーンテキストもいけるが、圧縮形式もいけるみたい。emp.zipを選択してみた。

![004.png](https://qiita-image-store.s3.amazonaws.com/0/3470/90eed784-ba33-3e9a-b32d-542b3c4a4514.png)

圧縮タイプを選択できるので、ZipDeflate を選択して、Zipの中身からインポートする。ちなみに、プレーンテキストは、NONEを選択する。

![005.png](https://qiita-image-store.s3.amazonaws.com/0/3470/9a08d6cf-208e-ef30-30bf-5d292f44a3e5.png)

ファイルフォーマットの指定。ある程度自動で、検出してくれるようだ。希望のフォーマットで認識できている。
これで取り込もう

![006.png](https://qiita-image-store.s3.amazonaws.com/0/3470/fd260fbb-6854-f000-c7fd-9fc8ec5c0fbf.png)

## 出力データソースの指定

次に 出力先として、SQL Database の設定をする。

![007.png](https://qiita-image-store.s3.amazonaws.com/0/3470/36d2e4e2-7c4b-5eb5-db56-ef76c42959d1.png)

データベースの設定。ここは難しいところは何もない。
![008.png](https://qiita-image-store.s3.amazonaws.com/0/3470/ba43f70e-aa4a-e8ac-01b1-b33a4b691614.png)

どこのテーブルに出力するかも選べる。簡単。
![009.png](https://qiita-image-store.s3.amazonaws.com/0/3470/9ec30def-54b4-7918-2952-bc35a149df2e.png)

## 重複データを避ける

1 つだけ Tips がある。普通にこの Task を実行すると、何回もタスクが実行されるので、データが重複して記録される。これは避けたいだろう。そういうときは、Repeatability Setting を設定するとよい。ここに、SQL のカスタムスクリプトを記述する。

今回は、重複データを避けるために、重複データを削除するSQLを記述した。書き方は次のブログからもらいました。[主キーのないテーブルから重複レコードを削除する](http://sotoattanito.hatenablog.com/entry/2015/10/20/230208)。正直 SQL Database のSQLにはなじみがないので、勉強せねば。これはまた別の機会に。

```SQL
WITH [duplicate_record] AS (
	SELECT
	ROW_NUMBER() OVER (PARTITION BY
			[FirstName]
			,[LastName]
			ORDER BY
			[FirstName]) AS [SEQ]
	,[FirstName]
	,[LastName]
	FROM
	[dbo].[emp]
)
DELETE FROM
	[duplicate_record]
	WHERE
	[SEQ] > 1;
```

![010.png](https://qiita-image-store.s3.amazonaws.com/0/3470/d978dc28-ceb2-741c-e246-f9b9f785160c.png)

並行実行を指定して

![011.png](https://qiita-image-store.s3.amazonaws.com/0/3470/11655f55-fdcb-5468-a5dd-9704c038e4ca.png)


実行すると確認画面がでて
![012.png](https://qiita-image-store.s3.amazonaws.com/0/3470/e1065296-70a2-00b5-76c3-12a321a53dc0.png)

## Task の実行
実行します！
![013.png](https://qiita-image-store.s3.amazonaws.com/0/3470/b2a3d817-a614-728d-6921-3eec8360a1b3.png)

きれいに、重複データが取り除かれて、データが格納されました。

![015.png](https://qiita-image-store.s3.amazonaws.com/0/3470/7c38eb0e-67a7-240e-6665-bf3340069c5c.png)

# おわりに

一番簡単な手順をためしてみましたが、深堀すると面白そうなテクノロジーですね。普段格闘している Istioのような生まれたてのものと比べるとさくっと動くのでむっちゃ楽ですね！