初めての Snowflake NativeApplication

初めての Snowflake NativeApplication
0_image

こんにちは、三村です。

今回は Snowfalke の新しい機能「NativeApplication」をご紹介いたします♪

※先日、Snowflake のイベント「ユニストアってなに?Hybrid Table&Native Application Frameworkデモ日本初公開!!!! 〜 イベント延期だけどSnowflakeコミュニティは熱いぞSP」に登壇させていただきました。他の方が紹介している技術も素晴らしいので是非ご覧ください。

Snowflake NativeApplication とは

NativeApplicationとは、開発者(プロバイダ)が作成したプログラムを、ユーザー(コンシューマ)が 使える仕組みです。

プロバイダ側のSnowflake環境でプロシージャを作成し、コンシューマ側のSnowfalke環境で実行できます。

プロシージャは、なんとプロバイダ側にあるデータを参照することができちゃうんです♪

コンシューマは、プロバイダに自社データを送信して処理を依頼する必要はありません。

一般的なAPIの構造は、

ユーザーが「処理に必要な情報」をプロバイダに提供し、

プロバイダは「情報に応じた回答」をユーザーに返します。

NativeApplication の構造は

プロバイダが保有する「データとアプリ」を ユーザーと「共有」し、

ユーザーが「自社環境」で 処理に必要な情報をアプリに提供して回答を得ます。

この 素晴らしい Snowflake NativeApplication 機能を使って、「逆ジオコーディングアプリ」を作成いたしました。

「逆ジオコーディングアプリ」とは、ポイントとポリゴンをマッチングさせ、緯度経度情報に住所(町丁目)をつけます。

結果は以下のとおり

お客様がお持ちの緯度経度情報と、truestarが保持している情報をマッチングするアプリです!

お客様がお持ちの情報は、truestarからは見えません。

truestarが保持している情報は、お客様からは見えません。

この仕組みを使えば、データのやり取りをする必要がなく、開発側(プロバイダ)もユーザー側(コンシューマー)も安心して運用できますね。

※2022年9月現在、「Snowflake NativeApplication 」機能はPrivate preview です。この 「逆ジオコーディングアプリ」をお使いになってみたい方は、弊社まで直接ご相談ください。

また、自社でこんなデータを持っているのだけど、加工処理をしてほしい等のご依頼も承っております。

どうぞよろしくお願いいたします。

Snowflake NativeApplication の作り方・使い方

ここからは 実際のコードで Snowfalke NativeApplication の作り方(プロバイダ側)と使い方(コンシューマ側)をご説明いたします。

<プロバイダ側>

NativeApplication は、プロバイダのDBやプロシージャを コンシューマーに共有することにより実現しています。(共有するリソースはコンシューマから見えるようにすることも、見えないようにすることもできます。)

まずは、コンシューマーに公開するデータベースとスキーマを作成します。

/* -----------------------------------
コンシューマーに共有するデータベースおよびスキーマを作成
----------------------------------- */
--データベース作成 
CREATE OR REPLACE DATABASE prepper_open_data_bank;
--スキーマ作成
CREATE OR REPLACE SCHEMA podb;

次に、コンシューマーが呼び出すプロシージャを作成します。今回は逆ジオコーディングのプロシージャを作成しました。

コンシューマー側の緯度経度情報に プロバイダ側の町丁目情報を付けて、新規にviewを作成する、というものです。注意する点は、作成した view に対して コンシューマーが参照できるように権限を付加することです。

これはJavaScriptで作成しましたが、Snowflakeでは他の言語も使用できますので、お得意な言語で作成してOKです。

/* -----------------------------------
Native Appを作成(逆ジオコーディングする)
----------------------------------- */
create or replace procedure prepper_open_data_bank.podb.reverse_geocoding(
VIEW_N varchar, // 町丁目情報を付与する、新規作成view名
TABLE_N varchar, // 緯度経度情報を持つテーブル名
LONGITUDE_N varchar, // 経度カラム名
LATITUDE_N varchar // 緯度カラム名
)
 returns FLOAT not null
 language javascript
as 
$
 var my_sql_command = ""; 
 var statement = ""; 
 var ret = 0;
 ・・・
/*
コンシューマー側に、viewを作成し、町丁目情報を付加する。
このとき、作成した view をコンシューマーが参照できるようにする。
*/
my_sql_command = 'GRANT SELECT ON VIEW PREPPER_OPEN_DATA_BANK.API.VIEW_N TO DATABASE ROLE APP_EXPORTER';
my_sql_command = my_sql_command.replace('VIEW_N', VIEW_N);
statement1 = snowflake.createStatement( {sqlText: my_sql_command} );
ret = statement1.execute();

return 0.0;
$
;

次に データベースロールの設定を行います。各オブジェクトへの権限を付与します。

注意点は、作成したアプリがプロバイダ側のテーブルを参照する場合、そのテーブルへの参照権限を付与することです。

/* -----------------------------------
コンシューマーに公開するデータベースロール 処理
----------------------------------- */
--データベースロールを作成 
CREATE OR REPLACE DATABASE ROLE prepper_open_data_bank.shared_db_role;
--データベースロールに、共有するデータベースへの権限を付与
GRANT USAGE ON DATABASE prepper_open_data_bank TO DATABASE ROLE prepper_open_data_bank.shared_db_role;
--データベースロールに、共有するスキーマへの権限を付与
GRANT USAGE ON SCHEMA prepper_open_data_bank.podb TO DATABASE ROLE prepper_open_data_bank.shared_db_role;
--データベースロールに、ネイティブアプリへの権限付与
GRANT USAGE ON PROCEDURE prepper_open_data_bank.podb.reverse_geocoding(varchar,varchar,varchar,varchar) TO DATABASE ROLE prepper_open_data_bank.shared_db_role;
GRANT USAGE ON PROCEDURE prepper_open_data_bank.podb.reverse_geocoding(varchar,varchar,varchar,varchar,varchar) TO DATABASE ROLE prepper_open_data_bank.shared_db_role;
--データベースロールに、ネイティブアプリで参照する、プロバイダー側のテーブルへの権限付与
GRANT SELECT ON TABLE PREPPER_OPEN_DATA_BANK.PODB.CITY_POLYGON_GC TO DATABASE ROLE prepper_open_data_bank.shared_db_role;
GRANT SELECT ON TABLE PREPPER_OPEN_DATA_BANK.PODB.STREET_POLYGON_GC TO DATABASE ROLE prepper_open_data_bank.shared_db_role;

そして、アプリのインストーラーを作成します。これは、コンシューマー側が共有したときに自動で走ります。

/* -----------------------------------
インストーラーの作成
----------------------------------- */
CREATE OR REPLACE PROCEDURE prepper_open_data_bank.podb.installer()
RETURNS STRING
LANGUAGE SQL
EXECUTE AS OWNER
AS $
begin
 --コンシューマー側にAPIというスキーマを作成し、APP_EXPORTER がアクセスできる権限を付与(アプリでこのスキーマにviewを作成する)
 CREATE SCHEMA API;
 GRANT USAGE ON schema API TO DATABASE ROLE APP_EXPORTER;

 --コンシューマーに公開するデータベースロールを APP_EXPORTER に付与
 GRANT DATABASE ROLE shared_db_role TO DATABASE ROLE APP_EXPORTER;
end;
$
;

最後に共有の処理を行います。

/* -----------------------------------
共有処理
----------------------------------- */
--共有を作成
CREATE OR REPLACE SHARE podb_share installer = prepper_open_data_bank.podb.installer();
--データベースを追加
GRANT USAGE ON DATABASE prepper_open_data_bank TO SHARE podb_share;
--スキーマを追加
GRANT USAGE ON SCHEMA prepper_open_data_bank.podb TO SHARE podb_share;
--インストーラースクリプトを追加
GRANT USAGE ON PROCEDURE prepper_open_data_bank.podb.installer() TO SHARE podb_share;
--コンシューマーに公開するデータベースロールを追加
GRANT DATABASE ROLE prepper_open_data_bank.shared_db_role TO SHARE podb_share;
--共有にコンシューマのアカウントを追加
ALTER SHARE podb_share ADD ACCOUNTS = XXXXXXX;

<コンシューマ側>

コンシューマー側では プロバイダの共有から 自分の環境に データベースを作成します。

CREATE OR REPLACE DATABASE prepper_open_data_bank FROM SHARE yi59161.podb_share;

今回のアプリは、コンシューマー側の緯度経度情報をアプリが参照するので、共有にその権限をロール経由で付与します。

--ロールを作成する
CREATE OR REPLACE ROLE my_app_role;
--ロールにデータベースの使用権限を付与する
GRANT USAGE ON DATABASE test TO ROLE my_app_role;
--ロールにスキーマの使用権限を付与する
GRANT USAGE ON SCHEMA test.public TO ROLE my_app_role;
--ロールにテーブルの参照権限を付与する
GRANT SELECT ON TABLE test.public.POINT_STATION_01 TO ROLE my_app_role;
--共有したデータベースにロールを付与する
GRANT ROLE my_app_role TO DATABASE prepper_open_data_bank;

アプリを呼び出します。

/*************************************
アプリの実行 
*************************************/
call prepper_open_data_bank.podb.reverse_geocoding(
'reverse_geocoding_view',
'test.public.POINT_STATION_01',
'LONGITUDE',
'LATITUDE'
);

これで、コンシューマー側に逆ジオコーディングされた情報(view)が作成されます。

呼び出しインタフェースについて

コンシューマー側で、その都度Snowflakeを立ち上げてNativeApplicationを実行するのは少し面倒です。

今回、C#でインタフェースを作成してみました。このプログラムではInitボタン押下で権限の付与処理を行い、Showボタン押下で viewを作成します。

SnowParkを使ったりして、いろんなインタフェースが作れそうですね。

また、今後SnowflakeはStreamlitと連携するそうです。そうなれば、コンシューマー側はブラウザインタフェースでアプリを呼び出せます。試しにちょっと作ってみました。

initボタン押下で権限付与処理を行います(Anaconda Promotに処理を表示)。Showボタン押下でviewを作成します。

いかがでしょうか?これからもSnowflakeから目が離せませんね!