こんにちは、三村です。
今回は 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から目が離せませんね!