Snowflakeを使い始めた頃から、ずっと「これがあればいいのに」と感じていた機能があります。それがネイティブのGit連携です。バージョン管理が効かない環境では、ちょっとした操作ミスでインフラを壊してしまうことも珍しくありませんでしたが、今ではその心配は不要になりました。SnowflakeのGit連携は2024年4月にリリースされた機能で、私自身も以前から繰り返しリクエストしていたものです。本記事では、この機能の中身、使い方、そして代表的なユースケースを紹介します。
SnowflakeのGit連携とは
SnowflakeのGit連携を使うと、Snowflakeアカウントを各種Gitプラットフォーム(GitHub、GitLabなど)とネイティブに接続し、リモートリポジトリの内容をSnowflakeアカウントと同期できます。同期にはリポジトリステージと呼ばれる特殊なステージを使用します。このリポジトリステージはリモートのGitリポジトリと同期され、ブランチやコミットなど一式を含むリモートリポジトリの完全なクローンを持つローカルリポジトリとして機能します。
この仕組みにより、リポジトリの完全なクローンをSnowflakeアカウント内で直接扱えるようになります。取得したファイルをSnowflakeアプリケーションで利用したり、ハンドラコードをリモートGitリポジトリに置いたUDFやストアドプロシージャを記述してリポジトリステージと同期させたりできます。コードをそのままバージョン管理下に置き、リポジトリが更新されるたびにステージをリフレッシュするだけで反映できます。
また、任意のブランチやコミットのファイルをSnowflake内から直接参照することも可能です。
なぜこの新機能が注目に値するのか
この連携によって、コードをバージョン管理下に置く開発ライフサイクルが大きくシンプルになります。ストアドプロシージャのハンドラコードを例に考えてみましょう。連携機能が登場する前は、バージョン管理をSnowflakeの外で自前で行う必要がありました。VS Codeでハンドラコードを書いてテストし、開発が終わったらリモートリポジトリにコミットしてバージョン管理下に置き、同時にそのコードをSnowflakeへデプロイして、当該コードをハンドラとするストアドプロシージャを作成しなければなりませんでした。
具体的には、コードを手動でSnowflakeステージにアップロードしてストアドプロシージャを作成するか、Snowflake CLIでアップロードとプロシージャ作成をまとめて行うかのいずれかでした。どちらにせよ、バージョン管理されたコードと直接結びついていない追加の手順が発生していました。コードを修正するたびに、開発、リポジトリへのコミット、Snowflake上のハンドラファイルの更新という流れを毎回繰り返す必要があったわけです。
ネイティブのGit連携がこの流れをどれだけ効率化してくれるかを見てみましょう。ハンドラコードをリポジトリステージから直接参照できるため、変更をコミットしてリポジトリステージを同期するだけで、ストアドプロシージャのハンドラは自動的に更新され、しかもバージョン管理下に保たれます。「バージョン管理」と「SPの更新」という分離したプロセスを別々に回す必要はなくなり、ワークフローが一本にまとまります。
SnowflakeのGit連携で接続できるGitプラットフォームは次のとおりです。
- GitHub
- GitLab
- BitBucket
- Azure DevOps
- AWS CodeCommit
Git連携のエンドツーエンド事例
この例では、シンプルなHello WorldのストアドプロシージャハンドラをPythonで書き、リモートのGitHubリポジトリにコミットしたうえで、Git連携を使ってSnowflakeに取り込みます。その後ハンドラコードを修正し、Git連携によってSnowflake内のSPハンドラコードがどれほど手軽に更新できるかを確認します。まず、これから構築する全体像を簡単な図で示します。
- まずVS Codeでハンドラコードをローカル開発し、GitHubリポジトリにコミットします。
- 次にSnowflake側で、リモートリポジトリを指すリポジトリステージを作成します。あわせて、Gitアカウントの認証情報を保持する新しいシークレットも作成します。
- リポジトリステージが用意できたら、リモートリポジトリと同期してコードをSnowflakeに取り込みます。
- 最後にSnowflakeでストアドプロシージャを作成し、ハンドラコードをリポジトリステージからインポートします。
それでは各ステップを詳しく見ていきましょう。
1. ハンドラコードの開発
hello_worldというシンプルなハンドラ関数を作成し、リポジトリにプッシュしました。これでSnowflake側で必要なオブジェクトを作成し、このリモートリポジトリを新しいリポジトリステージにリンクする準備が整いました。
2. シークレットの作成
まずはシークレットの作成からです。認証にはパーソナルアクセストークンを使用します。
3. API連携の作成
SnowflakeとGitHubをつなぐためのAPI連携も作成します。API_ALLOWED_PREFIXESパラメータには自分のGitHubアカウントのURLを指定し、認証には前の手順で作成したシークレットを使います。
4. リポジトリステージの作成
いよいよGitリポジトリステージを作成し、ここまでに用意した値を渡します。originには接続したいGitリポジトリを指定します。
5. リポジトリステージとリモートの同期
リポジトリステージが用意できたら、リモートリポジトリと同期します。
6. ストアドプロシージャの作成
これで準備完了です。SnowflakeとリモートGitリポジトリの連携が動作するようになりました。ストアドプロシージャのハンドラは、リモートリポジトリと同期したリポジトリステージから供給されます。それではストアドプロシージャを作成しましょう。
7. リモートリポジトリとの同期
実行してみるにはどうすればよいでしょうか。
次にコードを修正して、Snowflake側で更新がいかに簡単に取り込めるかを確認しましょう。今回もVS Codeでローカルに修正し、リモートリポジトリにコミットします。例として、メッセージを大文字に変換するだけのシンプルな変更を加えてみます。
変更をリポジトリにコミットしたら、Snowflake側のリポジトリステージを更新(同期)します。
1ALTER GIT REPOSITORY snowflake_git_demo FETCH;
これで、更新後のハンドラコードがSnowflake上で利用できる状態になりました。必要な作業はこれだけで、プロシージャの作り直しなどは不要です。ストアドプロシージャを実行して、コードが更新されていることを確認しましょう。
8. マージをトリガーにした自動更新
この処理は自動化できます。コード変更をフィーチャーブランチで管理し、メインブランチへマージするという一般的なGitワークフローを使っているとしましょう。プルリクエストがマージされたタイミングでALTER GIT REPOSITORYコマンドを実行するGitHub Actionsワークフローを組めば、メインブランチに新しいコードがプッシュされるたびにリポジトリステージが自動的に更新されます。
以下はシンプルな例です。SQL文の実行にはSnowSQLまたはSnowCLIのどちらでも構いません。
TORY command when the PR is merged, so the repository stage is automatically updated every time you push new code into your main branch!
Here is a simple example. You can use either SnowSQL or SnowCLI to run the SQL statement.
name: Deploying Stored procedure updates
env:
SNOWSQL_ACCOUNT: ${{secrets.SF_ACCOUNT}}
SNOWSQL_USER: ${{secrets.SF_USER}}
SNOWSQL_PWD: ${{secrets.SF_PASSWORD}}
SNOWSQL_DATABASE: ${{ secrets.SF_DATABASE }}
SNOWSQL_SCHEMA: ${{ secrets.SF_SCHEMA }}
SNOWSQL_ROLE: ${{ secrets.SF_ROLE }}
SNOWSQL_WAREHOUSE: ${{ secrets.SF_WAREHOUSE }}
on:
コードを展開
そして、GitHub Actionsワークフローを実行した結果は次のとおりです。
その他の操作
ここまででGit連携のセットアップ方法を見てきました。さらに知っておくと役立つ機能をいくつか紹介します。
Snowflake上でリポジトリを管理する
これまでの例で紹介したGitリポジトリ関連の操作は、リポジトリステージの作成と、リモートの更新を取得するALTERコマンドの2つだけでした。それ以外の代表的な操作を見てみましょう。
リポジトリのブランチを一覧表示する
リポジトリステージ内のすべてのブランチを、パスとコミットハッシュとあわせて一覧表示できます。
1SHOW GIT BRANCHES IN snowflake_git_demo;
リポジトリのファイルを一覧表示する
内部ステージや外部ステージのファイル一覧と同じ要領で、リポジトリステージのファイルもLISTコマンドで一覧表示できます。
1LS @snowflake_git_demo
リポジトリステージ
リポジトリステージの場合、ブランチ単位でファイルを一覧表示することもできます。
1LS @snowflake_git_demo/branches/main
特定のコミットハッシュ
1LS @snowflake_git_demo/commits/<<add_my_commit_hash>>
タグ名でファイルを一覧表示
1LS @snowflake_git_demo/tags/tag_name
リポジトリステージのプロパティを確認する
他のSnowflakeオブジェクトと同様に、リポジトリステージにもSHOWおよびDESCRIBEコマンドが用意されており、リポジトリステージの所在(データベース名・スキーマ名)、リモートリポジトリのorigin、GitとSnowflakeの接続に使うAPI連携、接続情報を保持しているシークレット名など、有用なメタデータを確認できます。
リポジトリのコードを実行する
ファイルをリポジトリに置けるのは便利ですが、そこに格納したコードを直接実行できたらさらに便利だと思いませんか。SnowflakeにはEXECUTE IMMEDIATE FROMコマンドがあり、ファイルに書かれたSQLコードをそのまま実行できます。アカウント構成(ユーザー、ロール、ウェアハウスの作成など)をSQLファイルとしてリポジトリに置いておけば、このコマンドでファイルから直接実行できます。
EXECUTE IMMEDIATE FROM @snowflake_git_demo/branches/main/sql/users.sql
リポジトリのコードをワークシートにコピーする
リポジトリステージに保存したファイルのコードを、ワークシートにコピーすることもできます。対象は.sqlファイルと.pyファイルで、コピー後はSnowsightのワークシート上で編集や実行が可能です。コピーしたいファイルを開き、Copy into worksheetを選択するだけです。
制限事項
変更をリポジトリに書き戻したい場合は、ローカルにあるリポジトリのコピー側で行う必要があります。現時点では、Snowflake側のリポジトリは原則として読み取り専用で、書き戻しに対応しているのはNotebooksだけだからです。そのため、リポジトリへの書き戻しはNotebooks経由に限られます。執筆時点でのその他の制限事項は次のとおりです。
- 読み取り専用のサポート(上記参照)
- パブリックインターネット経由のアクセスのみに対応。プライベートネットワーク内のリポジトリにはアクセスできません。
- リポジトリステージはData Sharingで共有できません。
- アプリケーションパッケージ内にリポジトリステージを作成することはできません。
- 顧客側のネイティブアプリ内にリポジトリステージを作成することはできません。
- リポジトリステージ上のファイルへのアクセスは、Snowflakeの内部ステージのファイルへのアクセスと比べて遅い場合があります。データ取り込み用途には使用しないでください。
- サブモジュールは現在サポートされていません。
SnowflakeのGit連携のユースケース
エンドツーエンドの例では、Git連携の活用例の一つとして、プロシージャやUDFのコードをリモートリポジトリでバージョン管理する方法を紹介しました。しかし、ユースケースはこれだけではありません。
Git連携は、DevOpsの考え方でアカウントを運用するうえでも欠かせません。Snowflakeオブジェクト(データベース、ウェアハウス、ユーザー、ロールなど)の定義を、CREATEやALTERを含むSQLファイルとしてリモートリポジトリで管理し、CI/CDパイプラインの一部として実行できます。リポジトリステージのおかげで、それらの定義のコピーをSnowflake上で直接扱えるため、外部のランナーを介さずにそのままコードを実行してオブジェクトをデプロイできます。
もう一つのユースケースは、ネイティブアプリやStreamlitアプリでの活用です。コードをリモートリポジトリとネイティブに統合できます。さらに、Snowflakeでデータ変換(タスクを使ったDAGや動的テーブル)を行っている場合は、パイプラインの定義をバージョン管理下に置き、リポジトリステージやSnowflake環境とスムーズに統合できます。
Tomáš Sobotík・Senior Data Engineer & Snowflake SME at Norlys
Tomasは長年にわたるSnowflake Data SuperHeroであり、Snowflake全般に精通したエキスパートです。データ業界での経験は10年以上に及び、さまざまな業界・技術のプロジェクトでSnowflakeのデータエンジニア、アーキテクト、管理者を務めてきました。コミュニティのコアメンバーとしても積極的に知見を発信し、多くの人にインスピレーションを与えています。また、O'Reillyのインストラクターとして、ライブのオンライントレーニングも担当しています。