Azureでデータ分析基盤作ってみた - ②ADFの構築とETL処理

Azureでシンプルなデータ分析基盤を作る検証をしています。
[Azureでデータ分析基盤作ってみた - ①Synapseの構築](https://qiita.com/m-duct/items/0123f072b1d2c0928367)という記事の続編として、ADFの構築とETL処理について記載します。

## 構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/726ff053-aad9-5f39-551e-5f102a275d74.png)
1つのリソースグループの中にストレージアカウント、ADF、Synapseワークスペースを作成します。
ストレージアカウント(ADLS Gen2)に置いたcsvファイルをparquetファイルに変換すると同時に、データ型の変換も行います。
SynapseではサーバーレスSQLプールを使って外部テーブルを作成し、Power BIから外部テーブルを参照できるようにします。

## 作業内容
以下の順番で作業を行いました。
本記事では「2. ADFの構築とETL処理」について記載します。

[1. Synapseの構築](https://qiita.com/m-duct/items/0123f072b1d2c0928367)
リソースグループ、ストレージアカウント、Synapseワークスペースを構築
2. ADFの構築とETL処理
ADFインスタンスを構築後、ADFでデータ型およびファイル形式の変換（今回はここ）
[3. 外部テーブル作成](https://qiita.com/m-duct/items/615fc5acb562284c3a04)
parqutファイルを参照する外部テーブルをSynapseに作成してPower BIから参照する

## 今回の構築範囲
ADFインスタンスを構築後、ADFでETL処理をするために必要なコンポーネントの設定をします。

### 作成するもの
#### ADFインスタンス
Azure上でデータ統合サービスとして提供される個別の環境のこと。

#### リンクサービス
Data Factoryが外部リソースに接続するために必要な接続情報を定義するコンポーネント。
今回は事前に作成したストレージアカウントに接続するための情報を定義します。

#### データセット
データストア内のデータ構造を表すもの。
今回はストレージアカウントに格納したcsvファイルをparquetファイルに変換して保存するため、csvファイル用のデータセットとparquetファイル用データセットの2種類を作成します。

#### データフロー
データ変換ロジックを作成して管理するもの。
今回はデータ型の変換を行うパイプラインを1つ作成します。

#### パイプライン
1つの作業単位を実行するための複数のアクティビティから成る論理的なグループ。
今回は先に作成した1つのデータフローを実行するためにパイプラインを使います。

## 利用するデータ
東京都オープンデータカタログサイトに掲載されている[令和6年度認可保育園等一覧（公立・公私連携）](https://catalog.data.metro.tokyo.lg.jp/dataset/t132047d0000000013/resource/1d98fdef-39ac-4e64-a96f-51b63c9907a0)というデータを利用します。
赤枠のリンクをクリックするとcsvファイルがダウンロードできるので、構築作業の前にローカルに保存しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/1aea1852-52ac-89b2-5b33-180f226a7aad.png)

## 構築作業
### csvファイルの格納
前の記事で作成したストレージアカウントのファイルシステム内にinputフォルダとoutputフォルダを作り、inputフォルダに上記のcsvファイルをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/475dcf08-7f45-059a-3afe-ef353af623d2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/84759811-be53-5a4c-0afb-344c2a2b910c.png)

### ADFインスタンスの構築
Azure Portalの上部の検索窓から「データファクトリ」を検索し、選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/e2e2f1c6-6db0-e453-8a17-464e98412d4c.png)

データファクトリの画面で「+作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/ab2b2678-7179-d74d-d423-ef137c41413e.png)

基本タブに以下の情報を入力します。
- サブスクリプション：任意のサブスクリプションを選択します
- リソースグループ：前の記事で作成したリソースグループを選択します
- 名前：任意のADFインスタンス名を入力します
- リージョン：任意のリージョンを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/42b4cd27-a10c-6b30-9889-30df7fa11721.png)

Git構成タブ、ネットワークタブ、詳細タブ、タグタブはデフォルトのまま「次へ」をクリックします。
確認と作成タブで設定を確認したら「作成」をクリックしてデプロイが完成するまで待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/72dcd976-7c3d-edd7-05ce-a5a31f343168.png)

デプロイが完了したら作成したADFインスタンスからAzure Data Factory Studioを起動します。
以降「パイプラインの作成と実行」の完了までAzure Data Factory Studioにて作業を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/eca779be-8839-41f3-eeaf-71b4bc768f83.png)

### リンクサービスの作成
管理→リンクサービス→+新規をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/d38e2013-c0ad-5071-c598-f86fe3caa7a6.png)

データストアで「Azure Data Lake Storage Gen2」を選択し「続行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/ef1b5717-1f17-f738-889d-6fc997dc53c5.png)

任意のAzureサブスクリプション、前の記事で作成したストレージアカウント名を選択し、「作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/506300ed-3066-a7eb-b6a2-b00f350ce11f.png)

リンクサービスが作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/3f83b17d-187e-4999-2018-c5482ef047f2.png)

### csvファイル用データセットの作成
作成者→データセット横の数字→新しいデータセットをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/e8d94527-18cd-4776-f8ca-192f3eef01cf.png)

「Azure Data Lake Storage Gen2」を選択し「続行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/81612d50-6be3-d41d-aeca-03fef4844652.png)

「DelimitedText」を選択し「続行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/2ba955b1-22e1-625a-8a76-5f95a0345ef1.png)

先ほど作成したリンクサービスを選択し、ストレージアカウントに格納したcsvファイルまでのパスを入力します。
スキーマのインポートは「接続またはストアから」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/e9a7e330-e916-25c6-ab1a-e8fec3600c55.png)

エンコードの設定がデフォルトでは既定(UTF-8)になっていますが、csvファイルのエンコードはSHIFT-JISであるため変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/f3ee6682-0d7a-f9be-0dd8-c2c28c481561.png)

スキーマタブでデータのスキーマを確認すると文字化けしていました。。
が、スキーマのインポート→接続またはストアからをクリックすると、文字化けが直りました！
csvファイルに含まれている全てのスキーマが一覧化され、どのスキーマもString型になっていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/2b0f6555-a4b9-e6c4-7307-1aa68b7c9260.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/e036c36d-c4a8-3cc6-faaf-084da099659e.png)

### parquetファイル用データセットの作成
データストアの選択で「Azure Data Lake Storage Gen2」を選択し「続行」をクリックするところまではcsvファイル用データセットの作成と同じです。

形式の選択では「Parquet」を選択して「続行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/9ca3704d-ef52-27dd-a74d-3d89d4d0548f.png)

先ほど作成したリンクサービスを選択し、ファイルパスでoutputフォルダまでのパスを入力します。
スキーマのインポートは「接続またはストアから」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/97773b2d-8f47-ff80-0107-1bd50d9e3554.png)

parquetファイル用データセットが作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/c58f1392-379e-cff8-064a-8c248d2bf811.png)

### データフローの作成
作成者→データフロー横の数字→新しいデータフローをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/7ef3a9b8-cf12-41f3-db28-66a51899105f.png)

ソースの追加の横にある「↓」をクリックして「ソースの追加」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/c3ccde46-7866-8ea7-0364-58ed1fc60ceb.png)

ソースの設定タブのデータセットで先ほど作成したcsvファイル用のデータセットを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/65a664b8-f48f-4ccd-767c-b23fb6d0fe95.png)

検査タブで全てのカラムのデータ型がstringになっていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/c8b0bf40-786a-9691-3a93-b65cf4817e65.png)

source1の横の「＋」をクリックして「派生列」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/67068927-2caf-8864-d27e-4855e831e639.png)

今回は「通し番号」という列のデータ型をint型に変換します。
列で「通し番号」を選択し、「式ビルダーを開く」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/11d77b16-a4e7-b585-b968-f6e41c132e0d.png)

「toInteger」と「通し番号」をクリックして「toInteger({通し番号})」という式を作成し、「保存して終了」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/9d87805b-9e6a-a79c-8b96-e87345c96147.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/763bff2a-59b9-d648-92ef-24ce167e401c.png)

元の画面に戻ったら、式に「toInteger({通し番号})」と入力されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/84bb9ea7-11ff-aa47-9d74-2ab4ff34e4cf.png)

検査タブを開いて通し番号のデータ型がintegerになっていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/df7d81b0-3f4b-83d0-113a-6d273802bca4.png)

次にデータの保存先を指定します。
derivedColumn1横の「＋」をクリックして「シンク」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/cb6989c3-3f95-8fb5-2ab6-a8d62d8ef472.png)

シンクタブのデータセットで先ほど作成したparquetファイル用のデータセットを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/e13979ff-e13b-d28f-1669-26f4babc0a3d.png)

検査タブで通し番号のデータ型がintegerになっていることを確認できたらデータフローの作成は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/d7c0fd3c-bcb4-68b0-a9aa-6c41f9fbc764.png)

### パイプラインの作成と実行
作成者→パイプライン横の数字→新しいパイプラインをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/d72869d1-74e2-c2b3-a91c-06baa9fdc826.png)

先ほど作成したデータフローをパイプラインの画面にドラッグ＆ドロップしたらパイプラインは作成完了です。
パイプラインを実行する前に「すべて発行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/6d9821e9-fbcc-96c0-8da5-ed60ddea1944.png)

これまで作成したパイプライン1つ、データセット2つ、データフロー1つが保留中の変更状態になっていることを確認して、「発行」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/0a1a612f-647b-527c-cc8c-54671c003ea1.png)

発行が完了したら、トリガーの追加→今すぐトリガーをクリックします。
その後パイプライン実行で「OK」をクリックするとパイプラインの実行が始まります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/58bd8c25-9415-bfa4-0072-68dc11e78161.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/a0552847-a403-f030-28b5-dc21089b83c3.png)

実行結果は、モニター→パイプライン実行で確認できます。4分ほどで状態が成功になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/d1e69552-136c-4b0b-2da1-33a8dcca5ea8.png)

### parquetファイルの確認
ストレージアカウントに作成したoutputフォルダ配下を確認すると、parquetファイルが作成されていました！
次の記事ではSynapseに外部テーブルを作成して、parquetファイルに対してクエリを実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/f37cf69e-99fe-51b3-52fb-ed1c77f8b3f4.png)

## まとめ
ADFインスタンスの構築からETL処理までを行いました。
この記事がどなたかのお役に立てば幸いです。