Snowflake→AWS Glue→SnowflakeのETL

# はじめに

AWS GlueをETLとしてGUI操作でSnowflake上にあるテーブルのデータを加工してSnowflakeの別のテーブルに反映できることを確認した記録です。

# 前提

検証の前提として以下を実施済みの状態にしています。

- GlueからSnowflakeにアクセスできる（[参考:Snowflake 接続](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-programming-etl-connect-snowflake-home.html])）
    - Snowflake上で以下を実施
        - ロール作成
        - ウェアハウスへのUSAGEアクセス権の付与
        - データベースへのUSAGEアクセス権の付与
        - スキーマへのアクセス権の付与
        - テーブルへの権限の付与
        - ユーザーの作成
        - ユーザーへのロールの付与
        - AWS Secrets Managerで、Snowflakeの認証情報（ユーザー名、パスワード）を使用してシークレットを作成

こちらの記事にGlueからSnowflakeに接続できるまでを記載しています。
　[AWS GlueでSnowflakeと接続するために必要なこと](https://qiita.com/ysskjck/items/84c13f09670f47fd4c45)

# ゴール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/c21715db-6674-6db4-e07b-75620c46d856.png)

# やってみた

- Snowflake上でテーブル・データを準備
    - テーブル「MYTABLE」を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/c54451e1-9662-6894-66c9-a34cd395673e.png)

    - テーブル「MYTABLE」にデータを準備
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/27be038c-c31d-e7bc-dbb7-8b0be437fc2d.png)

    - テーブル「MYTABLE2」を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/ae9bcc99-5132-8cce-c127-b91fbd23a1e0.png)
（データは挿入せずレコードは空のまま）

- AWS Glueでジョブ作成
    - ソースノードの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/b4748dc2-f99a-7333-a6f2-60a5e55d1136.png)

    - 変換ノードの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/7637cab5-7620-9ba6-2f4b-120495f4b38d.png)
SQL Queryノードを使用してWHERE条件で抽出対象レコードを絞っています。

    - ターゲットノードの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/c84ae060-8b21-8009-507f-56c015a84dba.png)

- AWS Glueでジョブの保存と実行
    - ジョブの保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/80cddb84-fff3-6fd9-9ac9-1a6b7d736555.png)

    - ジョブの実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/2af8cc2c-4800-f808-98e6-637bc93cbd7a.png)

    - ジョブの実行結果の確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/ff1cd171-2c0d-eec1-639e-6a3829ba13ed.png)

- Snowflake上でテーブルの内容を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/daeb723a-974d-b1ac-bcff-f97643a8897d.png)
→できました！

# 注意点（つまづいたところ）
前述の例では変換ノードとして「SQL Query」を使用していますが、もともと「Filter」で実現しようとしていました。しかし、何度やっても同じ事象に阻まれて実現できませんでした。これがバグなのか、自分のミスなのかの判別がついていませんが、再現する事象を以下に記載しておきます。

- AWS Glueでジョブ作成
    - ソースノードの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/3bb6b5a6-7625-942a-86bc-efb63c4e7e43.png)

    - 変換ノードの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/cf64ab8a-5e5a-d89b-926f-3bf13618fd51.png)
ここでFilterノードを使用しています。「NO=1」というフィルター条件を設定しています。

    - ターゲットノードの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/d4222519-9a9f-51b3-5292-a610f288c219.png)

- AWS Glueでジョブの実行結果確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/35e8f75d-55dc-3cde-93bc-5d656494635c.png)
```言語:エラーメッセージ
Error Category: UNCLASSIFIED_ERROR; An error occurred while calling o119.pyWriteDynamicFrame. Status of query associated with resultSet is FAILED_WITH_ERROR. Numeric value 'aaa' is not recognized
```
何回試しても同じようにエラーになります。
スクリプトを見ると以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/15ae2f59-e9f7-e89e-c567-655c8696210e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838636/a64c630e-4798-1ffc-0975-a3e0817ba14e.png)
45行目のところでNOがVARCHARになっており、この時点で値が数値であるのに対してNO列をGlueが文字列型と認識しているように見えます。
これが原因なのか、なぜこうなるのかはわかっていませんが、遭遇した事象として記録しておきます。

# まとめ
AWS Glueを使用してSnowflakeにあるテーブルからデータを抽出・加工してSnowflake上のテーブルに反映することができました。