Azure Data Facoty / Synapse Analytics Mapping Dataflowでデータ品質検証によるエラーを起こす

## はじめに

Mapping Dataflowでデータ型の検証し、想定外のデータがある場合にエラーとする方法を紹介します。
確認した環境はデータ流出保護を有効にしたSynapse Analytics Workspaceです。
今後正規の方法が機能追加されるかもしれません。
→早速追加されてました。12/22 追記済み

2021/12時点の情報です。

>**注意**
>
>紹介する方法は条件によって動作しない可能性があるので、十分にテストしてからご利用ください。

## 参考

[マッピング データ フローでのアサート変換](https://docs.microsoft.com/en-us/azure/data-factory/data-flow-assert)

[マッピング データ フロー変換の概要](https://docs.microsoft.com/ja-jp/azure/data-factory/data-flow-transformation-overview)
[Azure Synapse Analytics ワークスペースでのデータ流出の防止](https://docs.microsoft.com/ja-jp/azure/synapse-analytics/security/workspace-data-exfiltration-protection)

## 確認手順

Dataflownの基本はわかることが前提の手順となります。

### 1. データの準備

適当なデータを用意します。
今回はAdventureWorksLTからcsv出力したデータを使いました。
AddressIDが数字で連携されるとして、これが文字列などが入ってしまう場合にエラーにしようと思います。


![2021-12-21-19-44-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a8103976-40db-6941-5ba8-e0c70958d7f3.png)


[AdventureWorks サンプルデータベース](https://docs.microsoft.com/ja-jp/sql/samples/adventureworks-install-configure?view=sql-server-ver15&tabs=ssms)


### 2. データフローの作成

#### 2.1. sorce

いたって普通にプロジェクションにより列を読み取ります。
プロジェクションの時点で型を決める場合、型に当てはまらない場合はNULLになります。
今回は文字列として読み取ります。


![2021-12-21-19-49-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/20b62162-0169-d3ca-de88-87a0398fed2f.png)



#### 2.2 assert

以下のように検証をかけることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a67b0462-18be-e240-2a13-4109bb4280ce.png)



#### 2.3. sink1

sinkを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/4a944a67-b0aa-651a-2466-2d45e479d018.png)


### 3. 動作確認

実行結果は以下の通り。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/aa2da947-ad7d-cd28-7cff-ad9742015c00.png)

### 4. データの内容変更して動作確認

先頭行を文字列にしました。

74e62a80beef.png)![2021-12-21-19-59-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/357b686a-3403-159c-a0a6-cebbdcd6a315.png)


実行結果は以下の通り。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/31d280ef-5077-d506-c68e-b91b20cf0388.png)


## rest版

assert を確認する前の方法を残します

#### 2.2. 条件分岐

AddressIDがintかどうかで分岐させます。

![2021-12-21-19-50-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0e97271c-2b79-40dd-f3df-ef8380e68d2e.png)

#### 2.4. sink2

ここがポイントになります。
異常データはRESTシンクしてしまいます。

![2021-12-21-19-54-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/9aacca61-2f93-e146-645e-07341c4d5922.png)


RESTシンクの中身です。
存在しないダミーurlを指定します


![2021-12-21-19-55-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/65adb854-f418-57f7-8174-5d97bb3f8333.png)


また、設定タブで挿入のみのシンクにします。

![2021-12-21-19-57-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/196dad8e-eb72-6acf-e290-63d1b59c5cec.png)


最後に書き込み順序を指定しておきます（影響ないかもです）

![2021-12-21-20-05-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/6bbdd675-48aa-cebc-86c2-511cb289ad5c.png)




### 3. 動作確認

実行結果は以下の通り。
sink1にのみデータ書き込みが発生しますが、sink2はなにもしません。

![2021-12-21-19-58-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8ce98f83-5ad8-73e0-c4d1-c0e1217d1e58.png)





### 4. データの内容変更して動作確認

先頭行を文字列にしました。

74e62a80beef.png)![2021-12-21-19-59-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/357b686a-3403-159c-a0a6-cebbdcd6a315.png)


実行結果は以下の通り。

![2021-12-21-20-03-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/b8c5498b-1368-0855-c3c5-4aa9e02cc09f.png)


## 補足

sink2が0となるので、他の方法もいけないかと検証しましたが、空行でデータ書き込み動作が発生するらしく、うまくいきませんでした。

Delta Lakeの場合：スキーマのマージを拒否したうえで異常データのみダミー列を投入→sink 0件の場合でもエラーとなる

SQL DBの場合：
- 存在しないテーブルをsink2にした→マッピングエラー
- 事前スクリプトででたらめなSQLを記述→パースエラー