Snowflakeから大規模な（TB級の）テーブルをFabricのコピーアクティビティで取り込む方法-Snowflake側でどのようなCOPY INTOオプションになっているかも確認-


Snowflakeのサンプルデータベースから、大規模な（10TB~30TBかそれ以上ある）テーブルをFabricのパイプラインのコピーアクティビティで取り込む際に苦戦したので、備忘録としてそのエラーと解決策、原因をまとめました。


# 試行錯誤前のエラー
### コピーアクティビティの設定値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/624b37cc-17f7-4c52-bbb0-712408901f09.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/b63a95d3-fcb4-48a0-8311-4a64e6da34fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/b14119c5-a625-415c-9ef1-0fbdeb47f2cc.png)


### 実行結果詳細

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/b4d2e62f-d68c-4d63-a149-324ece36414f.png)



### エラーメッセージ
ErrorCode=SnowflakeExportCopyCommandOperationFailed,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Snowflake Export Copy Command operation failed,Source=Microsoft.DataTransfer.Connectors.Snowflake,''Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Failed to execute the query command during read operation.,Source=Microsoft.DataTransfer.Connectors.GenericAdoNet,''Type=Apache.Arrow.Adbc.C.CAdbcDriverImporter+ImportedAdbcException,Message=[Snowflake] 100089 (42501): Failed to access remote file: access denied. Please check your credentials,Source=Apache.Arrow.Adbc,'



# 解決策
### 設定値
:::note info
重要設定
* ソースの[追加の Snowflake コピー オプション]にMAX_FILE_SIZEを1073741824に指定
* Snowflakeのウェアハウスのサイズを大きめにする（今回はXsmallからLargeに変更）
* Write batch timeoutをデフォルトから伸ばす（今回は8h）
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/a927bad1-33c3-4e1f-be54-47e9744d79b6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/a88c263c-d72b-43cf-a5f3-f486b45dd592.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/2fd3ee17-3e2e-461a-8d84-eae55def2358.png)


### 実行結果詳細

明らかに「ソースからステージングまでの期間」が前回より短縮された
「ステージングから目的までの期間」が約1時間半かかっていることからWrite batch timeoutは伸ばすことが必須だといえる（デフォルトの30分では不十分）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/50e9c7ef-24df-49be-b042-31510f787646.png)


Snowflake側からのCOPY INTOの結果詳細
FabricのUIから設定したMAX_FILE_SIZEがクエリに反映されていることが分かる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/fc9d6808-27e1-4ba0-b5fd-d042da685d76.png)




### 原因はワークスペースステージングではなく、「unloadに時間かかってる間にSASのトークンの期限が切れてる」からと予想

[Azure Data Factory または Azure Synapse Analytics を使用して、Snowflake V2 のデータをコピーして変換する](https://learn.microsoft.com/ja-jp/azure/data-factory/connector-snowflake?tabs=data-factory)から、ワークスペースステージングが怪しいと思ったが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/85f2562f-c31c-4ef8-a3f9-6b5173dcc88d.png)

失敗時のコピーアクティビティの裏側（Snowflakeのクエリ履歴から）を確認してい見るとワークスペースステージングのSASは正常に入力されていることを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/5f9dbe25-a0ac-4ee6-93af-ad66cb623b5e.png)


```SQL
COPY INTO 'azure://~~~/_system/services/DI/pipelines/~~~~/SnowflakeExportCopyCommand/' FROM "TPCDS_SF100TCL"."CATALOG_SALES" CREDENTIALS = (AZURE_SAS_TOKEN = '☺☺☺☺☺') FILE_FORMAT = (type = CSV COMPRESSION = NONE RECORD_DELIMITER = '
' FIELD_DELIMITER = ',' FIELD_OPTIONALLY_ENCLOSED_BY = '"' ESCAPE = '"' NULL_IF = '') HEADER = TRUE SINGLE = FALSE OVERWRITE = TRUE
```

試しに小さいテーブルでも（ワークスペースステージングON）試してみたところ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/1cefae56-af48-4046-a5be-c412f61c8678.png)

成功。原因はワークスペースステージングではないかもしれない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/1525eca4-e43e-42b3-ab43-68000bdb05a9.png)

以上などから
**原因はCOPY INTOが長時間に及んでいる際にSASトークンの期限が切れてることだと予想**



### 【参考】Fabricパイプラインの追加の Snowflake 形式オプションからParquetを指定するとエラー

Snowflakeの[COPY INTOのオプション設定](https://docs.snowflake.com/ja/sql-reference/sql/copy-into-location#optional-parameters)にも記載がある通り、formatTypeOptionsをParquetにしてやりたかったが、現状Fabricのパイプラインからは指定するとエラーになる。

### 設定値

ソースの追加の Snowflake 形式オプションに以下を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/e0d2eb72-38f3-4a42-a63b-8164e057c596.png)



JSONにも反映されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/9377981e-9fac-412e-a8d6-a355180793af.png)


### しかしエラーになる

以下エラーメッセージ

ErrorCode=SnowflakeExportCopyCommandOperationFailed,'Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Snowflake Export Copy Command operation failed,Source=Microsoft.DataTransfer.Connectors.Snowflake,''Type=Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,Message=Failed to execute the query command during read operation.,Source=Microsoft.DataTransfer.Connectors.GenericAdoNet,''Type=Apache.Arrow.Adbc.C.CAdbcDriverImporter+ImportedAdbcException,Message=[Snowflake] 002135 (42601): SQLコンパイルエラー：
オプション RECORD_DELIMITER は、ファイル形式型 PARQUETには無効です。,Source=Apache.Arrow.Adbc,'


### Snowflake側のクエリ履歴を確認

type=Parquetが反映されているのは確認できるが、
RECORD_DELIMITERなどtype=CSVの時のオプション項目がデフォルトで設定されており、これはParquet時には不要なためエラーとなっている。
現状これをFabric側から消去する方法は見つかっていない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921999/40af6440-c521-4741-990c-eccea9503771.png)






# 参考リンク

https://learn.microsoft.com/en-us/answers/questions/1519224/errorcode-snowflakefailtoaccess-when-copy-data-fro

https://community.snowflake.com/s/article/Troubleshooting-Error-Failed-to-access-remote-file-access-denied-Please-check-your-credentials

https://learn.microsoft.com/ja-jp/fabric/data-factory/connector-snowflake-copy-activity#source

# 用語

###  storageIntegration 
* Snowflake から外部ストレージ（Azure, AWS, GCP など）と連携するための仕組み
* ステージングとは別の概念 で、認証やアクセス権限を管理するための Snowflake の機能
* 例えば Azure Blob Storage や AWS S3 に直接データをコピーしたいときに使う

https://docs.snowflake.com/ja/user-guide/data-load-azure-config#option-2-generating-a-sas-token


### アンロード
アンロード（UNLOAD）はデータを外部ストレージやステージにエクスポートすること
一方で、ダウンロード（DOWNLOAD）はデータをローカルPC に保存
混同しないように注意

<details><summary>アンロードとダウンロードの由来</summary>
🔹 なぜ「アン（UNLOAD）」？

「UNLOAD」は、システム（データベースや DWH）から外部ストレージにデータを移すことを指す。
「システムからデータを外へ放出する（Unload = 降ろす）」というイメージ。
データベースやDWH では、データをそのまま保存することが多いから、外に出すときに「Unload（降ろす）」と言う。

🔹 なぜ「ダウン（DOWNLOAD）」？

「ダウンロード（DOWNLOAD）」は、主にユーザー視点で「データをローカル環境に取得する」ことを指す。
「上のシステム（クラウドやサーバー）から、手元（PC）にデータを持ってくる」
「Download」は「データが高いところ（クラウド）から落ちてくる（Down）」というイメージ。

✅ 「Unload」は昔からある英単語（元々の意味は「荷物を降ろす」）
✅ 「Download」はコンピューター時代に生まれた言葉（デジタルデバイスが普及してから）
</details>