Azure Data Factory (Synapse Pipelines)のMapping DataflowがSynapseにシンクする際に利用するメソッド

# Azure Data Factory (Synapse Pipelines)のMapping DataflowがSynapseにシンクする際に利用するメソッド

## 注意点

2021/10時点の情報です。

また、本記事でサポート回答を記載していますが、個別に投稿許可をいただいてます。
場合によりサポートで得た情報は公開を許可されないことがあるのでご注意ください

## はじめに

Azure Data Factory、あるいはAzure Synapse AnlayticsのGUIで作成可能なデータ変換機能である、[Mapping Dataflow](https://docs.microsoft.com/ja-jp/azure/data-factory/concepts-data-flow-overview)を使用する際に、MSサポートと連携して得た情報を共有します。
今回は、Synapse Analytics 専用SQL Poolに対してデータをロードする際に、Mapping Dataflowではどのような方式をとっているのか、また、その制御方法をまとめます。
※Copyアクティビティの話はここでは扱いません。

## Mapping Dataflowのステージング設定

Mapping DataflowはSynapse Analyticsを取得元（ソース）、登録先（シンク）対象にした際には、二つのタイミングでストレージを介してデータ取得/登録を行うことができます。
Synapse Analyticsは効率的にストレージのデータを取り込む/に直接データ書き出す機能をもっているため、それを呼び出すことで性能を確保しています。
※逆にステージングをおこなわないと以下のように性能が落ちる警告がでます。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/83ae9ee5-a936-d84b-0985-9e49d6c62a85.png)

## Synapse Analyticsで直接データを取り込み/書き出す機能について

COPYとPolybaseがあります。
元々はPolybaseだけでした。

### Polybase

[PolyBase によるデータ仮想化の概要](https://docs.microsoft.com/ja-jp/sql/relational-databases/polybase/polybase-guide?view=azure-sqldw-latest)
[PolyBase Transact-SQL リファレンス](https://docs.microsoft.com/ja-jp/sql/relational-databases/polybase/polybase-t-sql-objects?view=sql-server-ver15)

SQLServerにも存在する、ストレージ上のデータを仮想的にテーブルとみなしてT-SQLを実行できる機能です。
よく、Polybaseロードと言いますが、実際にはストレージ上のデータをSELECT -> CETAS後にターゲットテーブルにロードしています。

読み取りだけでなく、書き込み接続も可能です。

Polybaseにはデータを高速で取り込むためのチューニングがなされています。
[Azure SQL Data Warehouse loading patterns and strategies](https://docs.microsoft.com/ja-jp/archive/blogs/sqlcat/azure-sql-data-warehouse-loading-patterns-and-strategies)

#### 必要な権限

PolybaseをDataFactoryで実行する際、以下のT-SQLが自動実行されます。

1. CREATE MASTER KEY
2. CREATE DATABASE SCORPED CREDENTIALS
3. CREATE EXTERNAL DATA SOURCE
4. CREATE EXTERNAL FILE FORMAT
5. CREATE EXTERNAL TABLE
6. 作成したテーブルへのSELECT とターゲットへのインサート

従って、以下の権限が必要です。
- DBスコープのCONTROL
- 対象のテーブルへのINSERT
- ADMINISTER DATABASE BULK OPERATIONS

### COPY

[COPY (Transact-SQL)](https://docs.microsoft.com/ja-jp/sql/t-sql/statements/copy-into-transact-sql?view=azure-sqldw-latest)

取り込み専門の機能です。他者のDWH製品でもストレージ上のデータを取り込む機能として同じコマンドが採用されていることが多いです。
Polybaseには以下のようなファイルの要件があります。※Data Factoryではステージングストレージを有効化することで一度フォーマット変換して書き出してファイルフォーマットの要件がクリアされるようになっています。

Data Factoryで直接Polybaseを使う要件：
>ソース データ形式 は、次のように構成された Parquet、 ORC、または 区切りテキスト です。
>フォルダーのパスにワイルドカード フィルターが含まれない。
>ファイル名が空か、1 つのファイルを指している。 コピー アクティビティでワイルドカードのファイル名を指定する場合は、* または *.* の>みを指定できます。
>rowDelimiter が default、 \n、 \r\n、または \r である。
>nullValue が既定値のままか、空の文字列 ("") に設定されており、treatEmptyAsNull が既定値のままか、true に設定されている。
>encodingName が既定値のままか、utf-8 に設定されている。
>quoteChar、escapeChar、および skipLineCount が指定されていない。 PolyBase では、ヘッダー行のスキップがサポートされます。これ>は、firstRowAsHeader として構成できます。
>compression は、圧縮無し、 GZip 、または Deflate に設定できます。

これらの条件を緩和し、かつ、Polybaseを実行するのに必要な高権限を不要としているのがCOPYコマンドです。

#### 必要な権限

必要な権限は以下のように非常に少ないです。

>ADMINISTER DATABASE BULK OPERATIONS
>対象のテーブルへのINSERT

## シンク時のメソッドが決定する条件とは

Data Factoryにデータベース全体のCONTROL権限を与えたくない要件がある場合、Polybaseロードの利用は不可となります。
Copy Activityでは明示的に指定することができますが、Mapping Dataflowにはその設定が見当たりません。

### サポートへの確認結果

サポートに確認したところ、以下の回答を得ました。
GUI上のプロパティ設定ではなく、スクリプト内で記載されているということですね。

>データフローのスクリプトの中に 「allowCopyCommand：true」 が含まれている場合、COPYコマンドが使用されます。そうでない場合はPolybaseが使用されます。

確認方法

![script1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/6559f789-e8b6-0feb-20ad-efb9eeb3c9c2.png)


![script2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/76c27fd8-6265-0735-033c-3c77cbb5a2e8.png)



なお、これはシンク側でステージング設定を有効にした場合、既定でオンになるものですが、古いデータフローの場合だと、含まれていないことがあるそうです。

## 挙動の確認

Mapping Dataflow が実行したSQLで確認します。
上に行くほど最新のコマンドとなっています。

### ソースステージングの挙動

PolybaseのためにCREATEおよびDROPを実行しています。

![source_polybase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0f15482b-12f7-a4ba-eb7e-818948331662.png)


###　allowCopyCommand：trueが入っているときのステージングシンク

tempテーブル（idっぽいのがついたテーブル）を作成して、COPY後にターゲットテーブルにINSERT しています。

![sink_COPY.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/430de721-dbcf-832f-ab7a-20f1dfb8f45d.png)


### allowCopyCommand：trueがないときのステージングシンク

これはPolybaseのみが動作します。

こちらもtempテーブルを作成して、polybase外部テーブルからtempにINSERT後にターゲットテーブルにINSERT しています。

![sink_polybase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a41c3c2b-2e2c-ab77-b3c2-e5dca7bf6e8e.png)