セットアップスクリプトを作成する

このトピックでは、 CREATE APPLICATION コマンドの実行時にセットアップスクリプトを使用してアプリケーションオブジェクトにオブジェクトを作成する方法について説明します。

また、アプリケーションロールと、セットアップスクリプト内でのロールの使用方法についても説明します。

セットアップスクリプトについて

セットアップスクリプトには、 CREATE APPLICATION コマンドが以下のいずれかのコンテキストで実行されたときに実行される SQL ステートメントが含まれています。

  • コンシューマーが Snowflake Native App をインストールまたはアップグレードします。

  • プロバイダーは、アプリケーションパッケージをテストする際に、アプリケーションオブジェクトを作成またはアップグレードします。

注釈

セットアップスクリプトがサポートするのは SQL コマンドのみです。その他の言語はサポートされていません。

セットアップスクリプトの SQL ステートメントは、アプリが必要とするオブジェクトをアプリケーションオブジェクト内に作成します。これにはデータベースオブジェクト、ストアドプロシージャ、ビュー、 アプリケーションロール などが含まれます。

セットアップスクリプトは、アプリケーションパッケージに必要です。 manifest.yml ファイルは、セットアップスクリプトのファイル名と相対パスの両方を指定します。アプリケーションパッケージの作成時には、 manifest.yml ファイルとセットアップスクリプトの両方が名前付きステージに存在している必要があります。

セットアップスクリプトの制限

次は、セットアップスクリプト内では実行できません。

  • USE DATABASE

  • USE SCHEMA

  • USE ROLE

  • USE SECONDARY ROLES

  • ALTER <オブジェクト> コマンドを使用した LOG_LEVEL または TRACE_LEVEL プロパティの設定。

  • EXECUTE AS CALLER であるプロシージャの作成または呼び出し。

  • 名前付きステージ上のファイルを含めるために IMPORT を使用する、Snowparkユーザー定義関数(UDFs)またはプロシージャの作成。

  • アプリケーションパッケージに含まれていないコードを参照するプロシージャ、関数、または匿名コードブロックの呼び出し。

  • CREATE FUNCTION コマンドの使用時における、名前付きステージからのコードファイルのインポート。

  • EXECUTE AS CALLER として実行されるプロシージャを呼び出すための CALL の使用。

バージョン管理されたスキーマ内で作成されるオブジェクトには、さらに制限があります。

セットアップスクリプトで作成されたオブジェクトのコンシューマーへの可視性

セットアップスクリプトは、ほとんどのタイプのデータベースレベルオブジェクトを作成できます。セットアップスクリプトによって作成されたデータベースオブジェクトは、アプリケーションの内部オブジェクトです。コンシューマーがアプリをインストールすると、デフォルトでこれらのオブジェクトは非表示になり、コンシューマーアカウントに直接アクセスすることはできません。

注釈

プロバイダーは、 開発モードについて を使用してアプリケーションパッケージをテストするときに、セットアップスクリプトによって作成されたオブジェクトにアクセスできます。

プロバイダーは、アプリケーションロールを使用して、これらのオブジェクトをコンシューマーに表示することができます。セットアップスクリプト内で作成されたアプリケーションロールは、アプリケーションオブジェクトを所有するロールに自動的に付与されます。セットアップスクリプトによって付与されたアプリケーションのロールは、取り消すことはできません。

アプリケーションオブジェクトを所有するロールを持つユーザーは、組織内の他のロールにアプリケーションロールを付与できます。たとえば、セットアップスクリプトは、 APP_ADMIN などのアプリケーションロールを定義して、アプリケーション内のオブジェクトへのアクセス権限を付与できます。アプリケーションオブジェクトを所有するロールを付与されたユーザーは、これらのオブジェクトのアプリケーションロールを他のロールに付与することができます。

セットアップスクリプトが出力するメッセージのログレベルを設定します。

プロバイダーは、セットアップスクリプトの実行時に生成されるメッセージのログレベルを指定できます。追加情報については、 Snowflakeスクリプトでのメッセージのログ をご参照ください。

セットアップスクリプトのログレベルを構成するには、以下のシステム関数のいずれかを使用します。

たとえば、エラーメッセージをログするようにセットアップスクリプトを構成するには、セットアップスクリプトの最初に次のコマンドを追加します。

SYSTEM$LOG('error', 'Error message');
Copy

モジュラーセットアップスクリプトを作成する

一般的なアプリのセットアップスクリプトは、大規模で複雑になる場合があります。セットアップスクリプトをよりモジュール化して保守しやすくするために、プロバイダーは、複数のセカンダリセットアップスクリプトを呼び出すプライマリセットアップスクリプトを作成できます。

たとえば、プロバイダーは、異なるセットアップスクリプトを作成して、オブジェクトの作成、ビューの作成、ストアドプロシージャの作成などの異なる型のタスクを処理することができます。

CREATE APPLICATION コマンドを実行すると、 manifest.yml で指定されたメインセットアップスクリプトが実行されます。メインのセットアップスクリプトから追加のセットアップスクリプトを実行するには、 EXECUTE IMMEDIATE FROM コマンドを使用します。

プライマリセットアップスクリプトに含まれるセットアップスクリプトは、遭遇順に実行されます。これらのセカンダリセットアップスクリプトのセットアップスクリプトには、 EXECUTE IMMEDIATE FROM コマンドのインスタンスを含めることもできます。

アプリに複数のセットアップスクリプトを追加する

アプリに複数のセットアップスクリプトを追加するには、以下を実行します。

  1. プライマリセットアップスクリプトの場所を manifest.yml に追加します。

    artifacts:
      ...
      setup_script: scripts/setup.sql
      ...
    
    Copy
  2. プライマリセットアップスクリプトを作成します。

    次の例は、アプリの典型的なディレクトリ構造を示しています。

    @test.schema1.stage1:
    └── /
        ├── manifest.yml
        ├── readme.md
        ├── scripts/setup_script.sql
    
    Copy

    ここで、 setup_script.sql は、プライマリセットアップスクリプトです。

  3. セカンダリセットアップスクリプトを作成します。

    次の例は、複数のセットアップスクリプトを含むアプリの典型的なディレクトリ構造を示しています。

    @test.schema1.stage1:
    └── /
        ├── manifest.yml
        ├── readme.md
        ├── scripts/setup_script.sql
        ├── scripts/secondary_script.sql
        ├── scripts/procs/setup_procs.sql
        ├── scripts/views/setup_views.sql
        ├── scripts/data/setup_data.sql
    
    Copy
  4. プライマリセットアップスクリプト内で EXECUTE IMMEDIATE FROM コマンドを使用して、各セカンダリセットアップスクリプトへの相対パスを指定します。

    ...
    EXECUTE IMMEDIATE FROM 'secondary_script.sql'
    EXECUTE IMMEDIATE FROM './procs/setup_procs.sql'
    EXECUTE IMMEDIATE FROM './views/setup_views.sql'
    EXECUTE IMMEDIATE FROM './data/setup_data.sql'
    ...
    
    Copy

EXECUTE IMMEDIATE FROM コマンドに指定されたパスは、プライマリセットアップスクリプトの場所からの相対パスです。

セットアップスクリプトで EXECUTE IMMEDIATE FROM を使用する際の制限事項

セットアップスクリプト内で EXECUTE IMMEDIATE FROM を使用する場合は、以下の制限が適用されます。

  • EXECUTE IMMEDIATE FROM を使用して呼び出されたセットアップスクリプトでは、イベントログはサポートされていません。

  • EXECUTE IMMEDIATE FROM は、セットアップスクリプトでのみサポートされます。セットアップスクリプト以外のコンテキストでこのコマンドを使用することはサポートされていません。

  • コンシューマーアカウントの暗号化された外部ステージに格納されたファイルへのアクセスはサポートされていません。

セットアップスクリプトを作成する際のベストプラクティス

Snowflakeは、アプリのセットアップスクリプトを作成する際に、以下のベストプラクティスをお勧めします。

CREATE ステートメントのべき等形を使用する

セットアップスクリプト内で CREATE コマンドを使用してオブジェクトを作成する場合は、これらのコマンドの次に示すバージョンを使用することをSnowflakeはお勧めします。

  • CREATE OR REPLACE

  • CREATE IF NOT EXISTS

セットアップスクリプトは、インストール中やアップグレード中、複数回実行することができます。エラーが発生した場合、これらのオブジェクトはすでに存在している可能性があります。オブジェクトがバージョン管理されたスキーマ内で作成されている場合は特にそうです。

オブジェクト作成時にターゲットスキーマを含める

CREATE SCHEMA コマンドは、セッションコンテキストを変更しません。オブジェクトは、作成時にターゲットスキーマで修飾する必要があります。たとえば、セットアップスクリプト内でスキーマを作成するには、次のコマンドを使用します。

CREATE SCHEMA IF NOT EXISTS app_config;
CREATE TABLE IF NOT EXISTS app_config.params(...);
Copy

アプリケーションオブジェクトの外部から、アプリケーションオブジェクト内のオブジェクトを参照しない

アプリケーションオブジェクト内にあるオブジェクトを参照するオブジェクトは、アプリケーションオブジェクトの外部に作成しないでください。 Snowflake Native App Framework はこうしたオブジェクトの作成を禁止しませんが、コンシューマーが Snowflake Native App をインストールしたときに問題になる可能性があります。

たとえば、セットアップスクリプトがアプリケーションオブジェクトの外部にデータベース、スキーマ、およびビューを作成し、ビューがアプリケーションオブジェクト内のテーブルを参照する場合を考えてみましょう。このコンテキストでは、コンシューマーがデータベースの所有権を持ち、アプリケーションオブジェクトをドロップすると、データベース内のビューが破損します。

このベストプラクティスは、テーブル、ストアドプロシージャ、ユーザー定義関数、およびセットアップスクリプトで作成された参照に適用されます。

バージョン管理されたスキーマやバージョン管理されていないスキーマを使用する際に発生する可能性のある問題を考慮する

バージョン管理されたスキーマのオブジェクトとバージョン管理されていないスキーマのオブジェクトは相互参照できます。セットアップスクリプトでは、インストール中やアップグレード中に障害が発生した場合のことを考慮する必要があります。たとえば、プロバイダーは、最初の実行が失敗した場合にセットアップスクリプトが自動的に再実行される場合のことを考慮する必要があります。

たとえば、以下のようにオブジェクトを作成することを考えてみます。

CREATE OR REPLACE PROCEDURE app_state.proc()...;
GRANT USAGE ON PROCEDURE app_state.proc()
  TO APPLICATION ROLE app_user;
Copy

この例では、 CREATE OR REPLACE ステートメントが既存のプロシージャを置き換えており、そのプロシージャに以前与えられていた権限が暗黙的に削除されています。付与はスクリプトの後半で復元される可能性がありますが、スクリプトの実行時に失敗すると、コンシューマーはプロシージャにアクセスできなくなる場合があります。

再試行で解決できない問題(構文エラーなど)が原因でセットアップスクリプトが失敗した場合は、アプリが新しいバージョンまたはパッチにアップグレードされて付与が復元されるまで、コンシューマーはプロシージャにアクセスできません。

注意

このセクションのガイダンスは、 Snowflake Native App Framework のコンテキスト外部の タグマスキングポリシー行アクセスポリシー には適用されません。

タグとポリシーの割り当ては、バージョン管理されたスキーマの増分バージョンには伝搬しません。これらのシナリオは、エラーメッセージをトリガーします(タグを例として使用)。

  • バージョン管理されたスキーマでタグを作成し、そのタグを別のスキーマのオブジェクトに割り当てます。

  • バージョン管理されていないスキーマでタグを作成し、そのタグをバージョン管理されたスキーマのオブジェクトに割り当てます。

  • バージョン管理されたスキーマにテーブルやビューを作成し、バージョン管理されていないスキーマにタグが存在する場合は、そのタグをテーブルやビューに割り当てます。

  • バージョン管理されていないスキーマでテーブルやビューを作成し、タグがバージョン管理されているスキーマに存在する場合に、そのタグをテーブルやビューに割り当てます。

エラーメッセージは、

A TAG in a versioned schema can only be assigned to the objects in the same schema. An object in a versioned schema can only have a TAG assigned that is defined in the same schema.

ポリシーの割り当てがエラーメッセージのトリガーとなる場合、エラーメッセージには TAG ではなく POLICY が指定されます。

エラーメッセージを防ぐには、

  • Snowflake Native App プロバイダーはセットアップスクリプトを更新して、バージョン管理されたスキーマにタグまたはタグが設定されたオブジェクトが含まれている場合に、タグと同じスキーマ内のオブジェクトにタグ(またはポリシー)が設定されるようにする必要があります。バージョン管理されていないスキーマにタグまたはタグが設定されているオブジェクトが含まれている場合、セットアップスクリプトを更新する必要はありません。

  • アプリケーションのインストール時にこのエラーメッセージが Snowflake Native App コンシューマーに表示される場合、コンシューマーはプロバイダーにセットアップスクリプトを更新するように依頼する必要があります。さらに、コンシューマーは、バージョン管理されたスキーマに存在するタグをウェアハウスなどのアカウント内のオブジェクトに割り当てたり、バージョン管理されたスキーマに存在するポリシーをテーブルや列に割り当てたり、バージョン管理されたスキーマに存在するポリシーやタグを Snowflake Native App 内のオブジェクトに割り当てたりしないようにする必要があります。その場合、Snowflakeは同じエラーメッセージを返します。

バージョン管理されたスキーマ内でビューを定義する

常に、バージョン管理されたスキーマで共有コンテンツのビューを定義するようにします。これにより、新しい列やその他の属性が追加されたり削除されたりしても、アップグレード中にビューにアクセスするコードは、一貫したビューを使用できるようになります。

時間のかかる操作の互換性を確保する

大きな状態テーブルのアップグレードなど、非常に長時間の実行操作がセットアップスクリプトに必要な場合は、これらの更新が旧バージョンの既存の実行コードと互換性があることを確認してください。

アプリケーションロールについて

デフォルトでは、コンシューマーはアプリケーション内で作成されたオブジェクトに対する権限を持ちません。ACCOUNTADMIN ロールがあっても、アプリケーション のオブジェクトを表示することはできません。アプリケーション自体の外部に作成するオブジェクト(例: データベース)は、コンシューマーカウントの ACCOUNTADMIN ロールにのみ表示されます。

アプリケーションロールはデータベースロールに似ていますが、アプリケーション内でのみ作成することができます。データベースロールとは異なり、アプリケーションロールはアプリケーションの外部に存在するオブジェクトに対して権限を付与することができます。

アプリケーションロールは、アプリケーションのインストール時にセットアップスクリプトによって作成される必要があり、アプリケーションの所有者ロールに自動的に付与されます。そのロールで、コンシューマーアカウント内にある他のロールにアプリケーションロールを付与することができます。

注釈

アプリケーションロールは、アプリケーション内で作成できる唯一のロールの型です。たとえば、データベースロールはアプリケーション内では許可されていません。

同様に、アプリケーションロールはアプリケーションでのみ作成でき、通常のデータベースやアカウントレベルでは作成できません。

アプリケーションロールに付与された権限はすべて、アプリケーションのインストールに使用されるロールであるアプリケーションの所有者に渡されます。所有者はさらに、コンシューマーカウント内の他のロールにアプリケーションロールを委任することができます。

セットアップスクリプトは、アプリケーションロールを定義することもできます(例: USER)。このロールを使用すると、コンシューマーにはアプリケーションで提供される機能を使用するためのアクセス権が付与されます。セットアップスクリプトは、 READ_ONLY などのアプリケーションロールを定義して、アプリケーション内にある一部のデータ領域へのアクセスを制限することができます。

データベースロールとは異なり、アプリケーションロールはインストールされたアプリケーション以外のオブジェクトに対しても権限を付与することができます。したがって、アプリケーションの外部にあるオブジェクトに対する権限を付与するために使用できます。ただし、アプリケーションロール自体はアプリケーション内で作成する必要があります。

アプリケーションロールを操作するためにサポートされている SQL コマンド

Snowflake Native App Framework は、アプリケーションロールを操作するために以下の SQL コマンドを提供しています。

セットアップスクリプトでのアプリケーションロールの使用

セットアップスクリプトで定義されたアプリケーションロールは、アプリケーションインスタンスを所有するロールに自動的に付与されます。アプリケーションがインストールされると、アプリケーションのインストールに使用されるロールがアプリケーションの所有者になります。ただし、アプリケーションの所有者は、コンシューマーカウントの他のアカウントロールに権限を付与することができます。

アプリケーションロールは、アプリケーション内のオブジェクトに対する権限をコンシューマーに付与することができるようにします。例:

CREATE APPLICATION ROLE admin;
CREATE APPLICATION ROLE user;
GRANT APPLICATION ROLE user TO APPLICATION ROLE admin;

CREATE OR ALTER VERSIONED SCHEMA app_code;
GRANT USAGE ON SCHEMA app_code TO APPLICATION ROLE admin;
GRANT USAGE ON SCHEMA app_code TO APPLICATION ROLE user;
CREATE OR REPLACE PROCEDURE app_code.config_app(...)
GRANT USAGE ON PROCEDURE app_code.config_app(..)
  TO APPLICATION ROLE admin;

CREATE OR REPLACE FUNCTION app_code.add(x INT, y INT)
GRANT USAGE ON FUNCTION app_code.add(INT, INT)
  TO APPLICATION ROLE admin;
GRANT USAGE ON FUNCTION app_code.add(INT, INT)
  TO APPLICATION ROLE user;
Copy

この例では、セットアップスクリプトにより、 admin そして user という名前のアプリケーションロールが作成されます。そうすると、セットアップスクリプトは、アプリケーションコードを含むスキーマへのアクセス権を両方のアプリケーションロールに付与します。また、スキーマ内の add 関数へのアクセス権も付与します。 admin ロールには、 config_app プロシージャへのアクセス権も付与されます。

アプリケーションのロールおよびバージョン

アプリケーションロールはバージョン管理されません。つまり、アプリケーションロールをドロップしたり、バージョン管理されたスキーマにないオブジェクトから権限を取り消したりすると、アプリケーションの現在のバージョンやアップグレード中のバージョンに影響を与える可能性があります。アプリケーションロールを安全にドロップできるのは、それらのロールを使用するアプリケーションのバージョンをすべてドロップした場合のみです。

注釈

アプリケーションロールにオブジェクトの所有権を付与することはできません。つまり、セットアップスクリプトで定義されたアプリケーションロールは、インストールされた Snowflake Native App 内のオブジェクトにコンシューマーがアクセスすることを許可する場合にのみ使用します。