Snowflakeのいらないテーブルは自動で消す設定

## はじめに
いらない設定やテーブルが増え続けて行くこと、検証環境あるあるだと思います...
BigQueryはGUI上でテーブルの有効期限を設定することで不要なテーブルが自動で消えるようにできますが、Snowflakeでは類似の設定がありません。
きれいな環境を保ち続けるために、Snowflakeでも不要なテーブルは一定期間経過後に自動で消えるよう設定してみました！

今回はTROCCOのデータマート定義やワークフローを使用して設定しています。詳しい設定方法は本記事では省いているので、気になる方は下記記事も合わせてご参考いただけると幸いです

https://qiita.com/khpkymgc/items/dee2075cc0658673f727

## 今回のゴール
最終更新から15日以上経過したテーブルは自動で削除される

## 実装方法を考える
実装に必要な条件や工程を考えます。今回は下記が必要そうです。

**工程**

① 最終更新から15日経過したテーブルを特定してリスト化する
② リスト化したテーブル名をキーとしてテーブルを削除する
③ ループ実行して、複数テーブルの削除を1回で完了させる
④ スケジュール設定で定期的にタスクが実行されるようにする


**条件**

- 残しておきたいテーブルは削除対象から除外できること

## ループ実行とは？
カスタム変数ループ実行とは、タスクに埋め込んだカスタム変数に対して、複数の値を展開するよう設定できる機能です。詳細は下記ドキュメントをご参考ください。

https://documents.trocco.io/docs/loop-using-custom-variables?highlight=%E3%83%AB%E3%83%BC%E3%83%97%E5%AE%9F%E8%A1%8C

## ①最終更新から15日経過したテーブルを特定する
Snowflakeでは、データベース配下に **INFORMATION_SCHEMA** が存在します。このスキーマ配下の **table** 内にある **LAST_ALTERED** カラムが最終更新日時となっているようです。
これを利用して、最終更新が15日以上前のテーブルを特定しリスト化したいです。

TROCCOのデータマート定義を使って、「最終更新が15日以上前のテーブルを特定しリスト化するクエリ」を設定していきます。

下記のようなクエリになりました。
SELECT文で情報の取得元を指定し、WHERE句で**～でない**という条件をつけることで削除の対象外とする設定をいれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/244bfeaa-0de8-37bb-9408-95889a7338da.png)

::: note info
削除対象から除外するテーブルを追加設定しなくても良いように、削除対象外のテーブル名の先頭には **demotable_** をつける運用にします
:::

::: note info
**今日から15日後** という条件は毎回日時を指定するのが面倒なのでカスタム変数を使いました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/2d6dfc23-b474-c12a-3409-f8d5b779108e.png)
:::

上記クエリの結果を **delete_table_list** に出力するようGUIで設定していきます

![スクリーンショット 2025-01-14 160154.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/f8333015-7cdd-fa73-eb3f-35f12231b947.png)

設定に問題がなければ、保存します。


## ②リスト化したテーブル名をキーとしてテーブルを削除する
同じくTROCCOのデータマート定義でテーブルを削除するクエリを設定します。

SELECT文以外を使用するため、**自由記述モード**を利用し下記のようなクエリを設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/482c47fb-c0de-29a5-588e-5fa7dfb946a6.png)

::: note info
削除する対象のテーブル名はカスタム変数で指定します。
値は、このあとのループ実行の設定に依るため、適当で大丈夫です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/6044f3de-c103-45d8-d1ac-6b2795b35ffb.png)
:::

設定に問題がなければ、保存します

## ③ループ実行して、複数テーブルの削除を1回で完了させる
これまで設定したものをTROCCOのワークフローで組み合わせて、自動で複数テーブルの削除が実行されるようにします。

まず、ワークフローでタスクを下記のように配置しました。
①が完了したら②の実行に移るよう設定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/55971210-2ac5-0f20-1c68-056c45fc2c00.png)

②のタスクに対して**ループ実行**を設定します。
対象タスクの **･･･** から、**編集** を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/8db1e50f-8daf-9479-a153-7bae1743efa6.png)

**カスタム変数でループ実行**にチェックを入れます。
**対象カスタム変数**では、②で指定したカスタム変数(```$table_name$```)を選択します。
その他、クエリの実行先となるSnowflakeの接続情報等を設定します。

クエリでは、SELECT文で、テーブルの削除対象リスト(delete_table_list)のテーブル名が入っているカラム(TABLE_NAME)から値を取り出すように設定します。

![スクリーンショット 2025-01-14 163523.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/3fa7de98-6bb8-5c0b-fe75-a021aee39296.png)


上記のように設定することで、```$table_name$```に削除対象のテーブル名を1つずつ挿入し、いれる値がなくなるまで繰り返し実行してくれます。

ループ実行の設定は以上となるので、保存します。

## ④ スケジュール設定で定期的にタスクが実行されるようにする
設定した内容が定期的に自動で実行されるようスケジュールの設定をします。

設定済みのワークフローの一覧から、今回設定したものをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/2599f025-95b5-0603-c7e8-c571686720ef.png)

下にスクロールすると、**スケジュール設定**があります。
15日に1度ワークフローを実行して不要なテーブルのチェックや削除を行うようにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/1e277b54-a48e-bd12-8967-b87bda39f8c7.png)

設定画面はこんな感じです

![スクリーンショット 2025-01-14 164953.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/56749d1b-134f-f9ed-a4f7-0942b24b2fc4.png)

これですべての設定が終了です！お疲れ様でした

## 実行してみる
ワークフローを実行してみます。
結果画面を確認するとジョブの実行は成功していました。

![スクリーンショット 2025-01-14 173609.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/ff281fe4-1685-c5ee-533d-af8eb9818175.png)

Snowflake側の状況も合わせて確認します。まずは①のタスクの結果からです。

Snowflakeに、テーブルの削除対象リスト**delete_table_list**が作成されていました。
データプレビューでみると、7つのテーブルがリストアップされています。
スキーマ名や最終更新日時を見て、削除の除外条件に当てはまるテーブルはリストアップされていないことが確認できました。

![スクリーンショット 2025-01-14 172655.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/86676a32-f553-78d1-1846-b52b28d4ff41.png)

②のタスクの結果も確認します。
ワークフローの結果画面から、②のタスクが7回実行されたことがわかります。
①でリストアップされたテーブル数と一致するため、問題なさそうです。

![スクリーンショット 2025-01-14 172922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/4efa5008-e23b-2cbb-4c38-a797f3351a26.png)

SnowflakeでPUBLICスキーマ配下のテーブルを確認しても想定外のテーブルの残存や削除はありませんでした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3929084/34cdce4d-8057-8884-ab4b-3391f7f06d09.png)


## おわりに
今回設定するときにつまずいた点は下記の2点でした。

- WHERE句のBETWEENで、**今日から15日後の間**を実行時に自動で入れてくれるようにしたい
- **delete_table_list**の**TABLE_NAME**カラムの値を自動で入れてくれるようにしたい

クエリはChatGPTにきいて、出てきたクエリの使い方を調べて正しいか確認するという方法で進めていました。
ただ、この方法だと上記のような複雑な条件を指定したときにクエリも複雑になりすぎて正しいかどうか自分では判断できないことがありました。
なので、できるだけ簡単なクエリで実行できないか考えて**カスタム変数**を利用してみました。

今まで、カスタム変数という存在は認識しつつも具体的な利用場面に出会わなかったため、なんとなく使うの難しい機能だな、という印象でした・・・。
いざ使ってみると、日付の指定であればGUIで簡単に設定できました！
また、ループ実行の設定でもSELECT文を書くだけで難しいクエリや設定は特に必要なかったので安心しました。**やっぱりGUIって便利！**

また便利なことができたら記事にします！