Snowflakeに入門してみた〜テーブル作成からストアド呼び出し編〜

# はじめに
**ARIのアドベンドカレンダに初参戦しました！**

https://qiita.com/advent-calendar/2023/ari-group

みなさま、いかがお過ごしでしょうか。
最近は現場で"Snowflake"という単語をよく耳にするようになりました。

:man_tone3:「データレイク環境を*Snowflake*にリプレイスしましょう。」
:man_tone4:「上流が*Snowflake*にリプレイスされたので、それの対応しといて。」
:older_man_tone2:「そこの*Snowflake*取ってー」

耳にする度に「あー、AWSのSnowファミリーのあいつね（違う）」と思っていた私ですが、そろそろ重たい腰を上げて入門してみようと思います。

# Snowflake？
Snowflakeとは、Snowflake社が提供する**クラウド型のデータウェアハウスサービス**で、強みは「柔軟」「マルチクラウド対応」「高度なセキュリティ」etc... とのこと。

個人的な印象としては、点在しているデータレイク環境を一元化する際に使用されているケースが多いように感じます。

# いざ、入門
百聞は一見にしかず！ということで、早速触れていきましょう。

## 1. トライアルアカウントへのサインアップ
Snowflakeさんは太っ腹で、**全サービスを体験できるトライアル**があるようです。
下記いずれかに当てはまることが終了条件のため、うっかり料金が発生してしまうこともなく安心です。

- サインアップ日から30日間
- 無料のクレジット（$400）をすべて使い切る

また、メールアドレスさえあれば登録可能で、クレジットカードなど**支払い情報も不要**とのことです。

https://docs.snowflake.com/ja/user-guide/admin-trial-account

エディションは「スタンダード」、クラウドプロパイダーは「AWS」で登録してみました。

## 2. コンソールにログイン
届いたメールからアクティベーションすると、コンソールにログインします。
サイドバーに色々並んでいますが、とりあえず3つ覚えておけば入門できそうです。

<dl>
  <dt>Worksheets</dt>
  <dd>ブラウザ上から「SQLクエリ」または「Pythonコード」を実行</dd>
  <dt>Data</dt>
  <dd>テーブルやストアドプロシージャを作成/管理</dd>
  <dt>Activity</dt>
  <dd>発行したクエリ履歴</dd>
</dl>

また、1日の終わりに [Admin] > [Usage] からいくら使用したか確認しておくと良いと思います。

## 3. テーブル作成
まず、テーブルを作成していきます。
[Worksheets] > [+] > [SQLワークシート] から、下記クエリを流していきます。

```SQL:データベース、スキーマ作成
CREATE DATABASE TEST_DATABASE;
CREATE SCHEMA TEST_SCHEMA;
```

スキーマを作成した後に、Pythonスクリプトを使ってテーブルを作成します。
今度は、[Worksheets] > [+] > [Pythonワークシート] からスクリプトを実行します。

```Python:テーブル作成
from snowflake.snowpark.types import StructType, StructField, IntegerType, StringType
import snowflake.snowpark as snowpark


def main(session: snowpark.Session):
    # 列定義
    schema = StructType([
        StructField('ID', IntegerType()),
        StructField('NAME', StringType()),
        StructField('TYPE', StringType()),
    ])

    # DataFrameの構築
    df = session.create_dataframe([
        [1, 'ウェンティ', '風'],
        [2, '鍾離', '岩'],
        [3, '雷電将軍', '雷'],
        [4, 'ナヒーダ', '草'],
        [5, 'フリーナ', '水'],
        [6, 'ニィロウ', '水'],
        [7, '胡桃', '炎'],
        [8, 'ファルザン', '風'],
        [9, '八重神子', '雷'],
        [10, 'コレイ', '草'],
    ], schema)

    # テーブルへのデータの保存
    df.write.mode('overwrite').save_as_table('TEST_TABLE')
    return df
```

先ほど作成したテーブルとスキーマを指定して実行すると、テーブルが作成されていることが確認できました！

![スクリーンショット 2023-12-04 18.25.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622097/3b6c7daf-5940-e5d8-1198-1eff7b95ce9a.png)

## 4. ストアドプロシージャ作成
テーブルが作成できたので、色々と遊んでみましょう。
[Worksheets] > [+] > [Pythonワークシート] からテーブルを参照してみます。

```Python:テーブル参照
import snowflake.snowpark as snowpark


def main(session: snowpark.Session):
    database = 'TEST_DATABASE'
    schema = 'TEST_SCHEMA'
    table = 'TEST_TABLE'

    query = f'SELECT * FROM {database}.{schema}.{table}'
    df = session.sql(query)

    return df
```

実行すると、先ほど作成したテーブルが表示されます。

![スクリーンショット 2023-12-04 18.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622097/5af72e77-572d-02a1-e2b8-559d57ef52e6.png)

少し捻ってTYPEで絞り込んでみましょう。

```Python:TYPEで絞り込み
import snowflake.snowpark as snowpark


def main(session: snowpark.Session):
    database = 'TEST_DATABASE'
    schema = 'TEST_SCHEMA'
    table = 'TEST_TABLE'
    type = '草'

    query = f"""
        SELECT * FROM {database}.{schema}.{table}
        WHERE TYPE = '{type}'
    """
    df = session.sql(query)

    return df
```

実行すると、TYPEが「草」のレコードだけ表示されています。

![スクリーンショット 2023-12-04 18.34.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622097/024c880c-ee5a-0826-e2dd-e4f0a151d468.png)

TYPEを引数で受け取ってDataframeを返すストアドプロシージャを作成してみます。

```Python:ストアドプロシージャ用に引数を設定
import snowflake.snowpark as snowpark


session = snowpark.Session


def main(session, type):
    database = 'TEST_DATABASE'
    schema = 'TEST_SCHEMA'
    table = 'TEST_TABLE'

    query = f"""
        SELECT * FROM {database}.{schema}.{table}
        WHERE TYPE = '{type}'
    """
    df = session.sql(query)

    return df
```

ワークシート右上の[Deploy]から、ストアドプロシージャを作成してみます。

| Key | Value |
|---|---|
| Procedure name | TEST_PROCEDURE |
| Handler | main |
| Parameters - type | VARCHER |

![スクリーンショット 2023-12-04 18.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622097/7907b460-930d-a23a-7a00-cbc8becd1985.png)

## 5. ストアドプロシージャ呼び出し

最後に作成したストアドプロシージャを呼び出してみましょう。
[Worksheets] > [+] > [Pythonワークシート] からスクリプトを記述します。

```Python:ストアドプロシージャ呼び出し
import snowflake.snowpark as snowpark


def main(session: snowpark.Session):
    database = 'TEST_DATABASE'
    schema = 'TEST_SCHEMA'
    procedure = 'TEST_PROCEDURE'
    type = '水'

    df = session.call(f'{database}.{schema}.{procedure}', type)
    return df
```

上手く呼び出せました！

![スクリーンショット 2023-12-04 18.59.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622097/3e16b180-14ec-6610-3ed1-34f5bce6febb.png)

# おわりに
テーブル作成からストアドプロシージャの呼び出しと、Snowflake未経験から初心者にランクアップできた気がします。
上記全て実施しても**1時間程度**で終わるため、皆さんもぜひ入門してみてください！