アプリケーションパッケージへのビジネスロジックの追加

このトピックでは、アプリケーションパッケージのセットアップスクリプトにアプリケーションロジックを追加する方法について説明します。また、アプリケーションパッケージで外部コードファイルを使用する方法についても説明します。

アプリケーションパッケージに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
Copy

このディレクトリ構造内の 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';
Copy

この例では、 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;
       }
   }
 $$;
Copy

外部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
Copy

次の例は、 JAR ファイルを使用してJava関数を作成する方法を示しています。

CREATE FUNCTION app_code.add(x INTEGER, y INTEGER)
  RETURNS INTEGER
  LANGUAGE JAVA
  HANDLER = 'TestAddFunc.add'
  IMPORTS = ('/JARs/Java/TestAddFunc.jar');
Copy

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
$$;
Copy

外部Pythonファイルの使用

次の例は、アプリケーションパッケージに外部Pythonファイルを含める方法を示しています。

CREATE FUNCTION PY_PROCESS_DATA_FUNC()
  RETURNS STRING
  LANGUAGE PYTHON
  HANDLER = 'TestPythonFunc.process'
  IMPORTS = ('/python_modules/TestPythonFunc.py',
    '/python_modules/data.csv')
Copy

相対パスに関する詳細については、 外部コードファイルの参照 をご参照ください

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";
  $$;
Copy

この例では、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;
Copy

この例では、 SQL で記述されたストアドプロシージャを定義し、Snowflake外部のシステムでホストされているアプリケーションを参照する 外部関数を作成 します。外部関数は API 統合を返します。

この例では、ストアドプロシージャの USAGE もアプリケーションロールに付与しています。コンシューマーは、セットアップスクリプトでこのプロシージャを呼び出す前に、この権限を Snowflake Native App に付与する必要があります。