アプリケーションパッケージにビジネスロジックを追加する¶
このトピックでは、アプリケーションパッケージのセットアップスクリプトにアプリケーションロジックを追加する方法について説明します。また、アプリケーションパッケージで外部コードファイルを使用する方法についても説明します。
アプリケーションパッケージにStreamlitアプリを含める方法については、 Streamlitを使用してアプリにフロントエンドエクスペリエンスを追加する をご参照ください。
ストアドプロシージャおよび関数の使用に関する考慮事項¶
Snowflake Native App Framework は、ストアドプロシージャ、ユーザー定義関数(UDFs)、および外部関数をアプリケーションパッケージに含められるようにします。これらは、 Snowflakeがサポートする言語 のいずれかで記述することができます。
アプリケーションコードをセキュアに追加する¶
Snowflake Native App 内にあるすべてのストアドプロシージャと UDFs は、アプリケーションとして実行され、インストールされた Snowflake Native App 内のすべてのオブジェクトにアクセスできます。これは、 SQL インジェクション攻撃につながる可能性があります。
Snowflake Native App 内で使用するプロシージャや関数を開発する場合、ユーザーからの入力を必要とするすべての SQL コマンドは、バインドパラメーターを使用して実行することをSnowflakeは推奨します。これには、プロシージャの引数を通じて提供される入力も含まれます。
詳細については、 ストアドプロシージャの作成 をご参照ください。
呼び出し元の権限と所有者の権限について¶
セットアップスクリプトによって作成されたプロシージャ、またはインストールされた Snowflake Native App 内で実行されたプロシージャはすべて、所有者の権限(EXECUTE AS OWNER)で実行する必要があります。
この制限が存在するのは、 Snowflake Native App が所有していないプロシージャに対して Snowflake Native App が呼び出し元の権限(EXECUTE AS CALLER)で実行されると、そのプロシージャは Snowflake Native App 自体として実行され、コンシューマーがコードを作成して Snowflake Native App や共有データコンテンツの内容を表示または変更できるからです。
詳細については、 Understanding Caller's Rights and Owner's Rights Stored Procedures をご参照ください。
セットアップスクリプトからコンテキスト関数を呼び出す際の制限事項¶
コンテキスト関数 は、ステートメントが実行されるコンテキストに関する情報を提供します。 Snowflake Native App Framework のコンテキスト内では、一部のコンテキスト関数は使用できません。使用できないコンテキスト関数は、ブロックされてエラーを返すか、常にnull値を返します。
一般に、 Snowflake Native App 内の共有データコンテンツに適用されるポリシーでコンテキスト関数を使用する場合は、注意が必要です。たとえば、 CURRENT_IP_ADDRESS のようないくつかの関数は、 Snowflake Native App のコンテキストによって動作が異なります。
クライアント組織内の名前空間に依存するコンテキスト関数を使用する場合は、他の名前空間の関数と競合する可能性があることに注意してください。たとえば、 CURRENT_USER を使用した行アクセスポリシーでは、同じユーザー名が複数のアカウントに存在する可能性があることを認識する必要があります。
次のテーブルは、 Snowflake Native App Framework でサポートされていないコンテキスト関数のリストです。
コンテキスト関数 |
共有コンテンツでブロック(nullを返す) |
セットアップスクリプトとストアドプロシージャでブロックされ、 Snowflake Native App が所有する UDFs (例外をスロー)。 |
---|---|---|
CURRENT_ROLE |
✔ |
|
CURRENT_ROLE_TYPE |
✔ |
|
CURRENT_USER |
✔ |
|
IS_ROLE_IN_SESSION |
✔ |
|
CURRENT_IP_ADDRESS |
✔ |
✔ |
CURRENT_AVAILABLE_ROLES |
✔ |
✔ |
CURRENT_SECONDARY_ROLES |
✔ |
✔ |
ALL_USER_NAMES |
✔ |
|
GET_USERS_FOR_COLLABORATION |
✔ |
|
CURRENT_WAREHOUSE |
✔ |
|
SYSTEM$ALLOWLIST |
✔ |
アプリケーションパッケージでSnowpark関数とプロシージャを使用する¶
Snowflake Native App Framework は、Java、Scala、Pythonでストアドプロシージャを作成するためのSnowparkライブラリをサポートしています。
外部コードファイルの参照¶
アプリケーションパッケージに含めることができるコードファイルには2種類あります。
参照されるファイル: バイナリ、ライブラリ、その他のコードファイルを含みます。これらのファイルは、アプリケーションパッケージで定義されたバージョンに固有です。これらのファイルは、アプリケーションパッケージにバージョンを作成または追加する際、ステージのルートディレクトリに配置する必要があります。
参照されるファイルは、アプリケーションパッケージのセットアップスクリプトで定義されないため、ユーザー定義関数やストアドプロシージャとは異なります。これらのファイルは、セットアップスクリプトで定義されるストアドプロシージャや UDFs などのインポートステートメントによって参照されます。
リソースファイル: 半構造化データ、構造化データ、バイナリ、たとえば機械学習モデルなどを含みます。また、これらのファイルは、アプリケーションパッケージがアクセスできる名前付きステージにアップロードする必要があります。
これらの種類のコードファイルを参照するストアドプロシージャ、ユーザー定義関数、または外部関数は、セットアップスクリプトのバージョン管理されたスキーマ内に作成する必要があります。バージョン管理されたスキーマ内でストアドプロシージャや関数を作成する場合は、名前付きステージのルートディレクトリに相対するコードファイルを参照する必要があります。
たとえば、名前付きステージのルートディレクトリが /app_files/dev
の場合、このディレクトリには以下のファイルとディレクトリが含まれます。
manifest.yml
ファイル。セットアップスクリプトを含むディレクトリ、たとえば
scripts/setup_version.sql
。セットアップスクリプト内でストアドプロシージャ、 UDF、外部関数などを作成する際にインポートされる参照ファイル。
libraries/jars/lookup.jar
libraries/jars/log4j.jar
libraries/python/evaluate.py
このシナリオでは、ディレクトリ構造は以下のようになります。
@DEV_DB.DEV_SCHEMA.DEV_STAGE/V1:
└── app_files/
└── dev
├── manifest.yml
└── scripts/
├── setup_script.sql
└── libraries/
└── jars/
├── lookup.jar
└── log4j.jar
└── python
└── evaluation.py
このディレクトリ構造内の JAR ファイルにアクセスするために、セットアップスクリプトで定義されたストアドプロシージャが、次の例に示すようにこれらのファイルを参照します。
CREATE PROCEDURE PROGRAMS.LOOKUP(...)
RETURNS STRING
LANGUAGE JAVA
PACKAGES = ('com.snowflake:snowpark:latest')
IMPORTS = ('/scripts/libraries/jar/lookup.jar',
'/scripts/libraries/jar/log4j.jar')
HANDLER = 'com.acme.programs.Lookup';
この例では、 IMPORTS ステートメントには、バージョンの作成に使用されたルートディレクトリ(例: manifest.yml
ファイルの場所)からの相対パスがあります。
JavaおよびScalaのコードをアプリケーションパッケージに含める¶
Snowflake Native App Framework は、ストアドプロシージャや外部コードファイルでのJavaとScalaの使用をサポートしています。
JavaおよびScala UDFs インラインを作成する¶
Snowflake Native App Framework は、 Java および Scala を含むストアドプロシージャの作成をサポートしています。ストアドプロシージャを定義するコードをセットアップスクリプトに追加する必要があります。
次の例は、Java関数を含むストアドプロシージャを示しています。
CREATE OR ALTER VERSIONED SCHEMA app_code;
CREATE STAGE app_code.app_jars;
CREATE FUNCTION app_code.add(x INT, y INT)
RETURNS INTEGER
LANGUAGE JAVA
HANDLER = 'TestAddFunc.add'
TARGET_PATH = '@app_code.app_jars/TestAddFunc.jar'
AS
$$
class TestAddFunc {
public static int add(int x, int y) {
Return x + y;
}
}
$$;
外部JavaおよびScala UDFs をインポートする¶
プリコンパイルされた UDFs を作成するための構文では、インポートされた JARs がバージョン管理されたアーティファクトのセットの一部として含まれている必要があります。プリコンパイルされた JARs を参照するには、 IMPORT 句で完全なステージ場所を指定する代わりに、相対パスを使用します。
パスは、たとえば IMPORTS = ('/path/to/JARs/from/version/root')
のように、フォワードスラッシュ1つで始まるバージョンを含むルートディレクトリからの相対パスにする必要があります。相対パスに関する詳細については、 外部コードファイルの参照 をご参照ください
以下に、コードファイルのディレクトリ構造の例を示します。
@DEV_DB.DEV_SCHEMA.DEV_STAGE/V1:
└── V1/
├── manifest.yml
├── setup_script.sql
└── JARs/
├── Java/
│ └── TestAddFunc.jar
└── Scala/
└── TestMulFunc.jar
次の例は、 JAR ファイルを使用してJava関数を作成する方法を示しています。
CREATE FUNCTION app_code.add(x INTEGER, y INTEGER)
RETURNS INTEGER
LANGUAGE JAVA
HANDLER = 'TestAddFunc.add'
IMPORTS = ('/JARs/Java/TestAddFunc.jar');
JavaおよびScala UDFs の制限¶
Snowflake Native App Framework では、JavaとScalaを使用する際に以下の制限があります。
インポートは、バージョン管理されたスキーマで作成された UDFs に対してのみ許可されます。
インポートは、相対パスを使用してのみバージョンのアーティファクトにアクセスできます。
バージョン管理されたスキーマ以外で作成された UDFs は、インラインでのみ作成できます。
相対パスは TARGET_PATH をサポートしていません。
アプリケーションパッケージにPythonコードを追加する¶
Snowflake Native App Framework は、ストアドプロシージャや外部コードファイルでのPythonの使用をサポートしています。
セットアップスクリプトでPython関数を定義する¶
Snowflake Native App Framework は、 Python でのストアドプロシージャの作成をサポートしています。
次の例は、Python関数を含むストアドプロシージャです。
CREATE FUNCTION app_code.py_echo_func(str STRING)
RETURNS STRING
LANGUAGE PYTHON
HANDLER = 'echo'
AS
$$
def echo(str):
return "ECHO: " + str
$$;
外部Pythonファイルを使用する¶
次の例は、アプリケーションパッケージに外部Pythonファイルを含める方法を示しています。
CREATE FUNCTION PY_PROCESS_DATA_FUNC()
RETURNS STRING
LANGUAGE PYTHON
HANDLER = 'TestPythonFunc.process'
IMPORTS = ('/python_modules/TestPythonFunc.py',
'/python_modules/data.csv')
相対パスに関する詳細については、 外部コードファイルの参照 をご参照ください
Python UDFs の制限¶
Snowflake Native App Framework は、Python UDFs に以下の制限を課しています。
インポートは、バージョン管理されたスキーマで作成された UDFs に対してのみ許可されます。
インポートは、相対パスを使用してのみバージョンのアーティファクトにアクセスできます。
バージョン管理されたスキーマ以外で作成された UDFs は、インラインでのみ作成できます。
アプリケーションパッケージに JavaScript 関数およびプロシージャを追加する¶
Snowflake Native App Framework は、 JavaScript API を使用して、ストアドプロシージャとユーザー定義関数での JavaScript 使用をサポートしています。
JavaScript エラーを処理する¶
アプリケーションパッケージ内で JavaScript を使用する場合、Snowflakeはエラーをキャッチして処理することを推奨しています。そうしないと、エラーが返すエラーメッセージとスタックトレースがコンシューマーに表示されます。データコンテンツとアプリケーションロジックの秘密を保持するには、機密性の高いオブジェクトやデータにアクセスされる場合にtry/catchブロックを使用します。
次の例は、エラーをキャッチしてメッセージを返す JavaScript ストアドプロシージャです。
CREATE OR REPLACE PROCEDURE APP_SCHEMA.ERROR_CATCH()
RETURNS STRING
LANGUAGE JAVASCRIPT
EXECUTE AS OWNER
AS $$
try {
let x = y.length;
}
catch(err){
return "There is an error.";
}
return "Done";
$$;
この例では、try/catchブロックを含む JavaScript ストアドプロシージャを作成します。ストアドプロシージャが try
ブロックでステートメントを実行する際にエラーが発生した場合は、コンシューマーに表示される「There is an error」というメッセージを返します。
try/catchブロックがないと、ストアドプロシージャは元のエラーメッセージとコンシューマーに表示される完全なスタックトレースを返します。
注釈
Snowflake Native App Framework がサポートする他の言語は、 Snowflake Native App で発生するエラーメッセージを墨消し処理して返します。
アプリケーションパッケージに外部関数を追加する¶
Snowflake Native App では、 外部関数 により、Snowflakeの外部にホストされているアプリケーションコードを呼び出すことができます。外部関数では、 API 統合オブジェクトを作成する必要があります。
API 統合はコンシューマー環境の外部との接続を可能にするため、コンシューマーは Snowflake Native App に統合する方法を提供する必要があります。
次の例は、セットアップスクリプトによって作成されたストアドプロシージャで統合を受け入れ、外部関数を作成します。この例では、アプリケーションパッケージのセットアップスクリプトで外部関数を作成する方法を示します。
CREATE OR REPLACE PROCEDURE calculator.create_external_function(integration_name STRING)
RETURNS STRING
LANGUAGE SQL
EXECUTE AS OWNER
AS
DECLARE
CREATE_STATEMENT VARCHAR;
BEGIN
CREATE_STATEMENT := 'CREATE OR REPLACE EXTERNAL FUNCTION EXTERNAL_ADD(NUM1 FLOAT, NUM2 FLOAT)
RETURNS FLOAT API_INTEGRATION = ? AS ''https://xyz.execute-api.us-west-2.amazonaws.com/production/sum'';' ;
EXECUTE IMMEDIATE :CREATE_STATEMENT USING (INTEGRATION_NAME);
RETURN 'EXTERNAL FUNCTION CREATED';
END;
GRANT USAGE ON PROCEDURE calculator.create_external_function(string) TO APPLICATION ROLE app_public;
この例では、 SQL で記述されたストアドプロシージャを定義し、Snowflake外部のシステムでホストされているアプリケーションを参照する 外部関数を作成 します。外部関数は API 統合を返します。
この例では、ストアドプロシージャの USAGE もアプリケーションロールに付与しています。コンシューマーは、セットアップスクリプトでこのプロシージャを呼び出す前に、この権限を Snowflake Native App に付与する必要があります。