创建安装脚本

This topic describes how to use the setup script to create objects in the app when running the CREATE APPLICATION command.

本主题还描述了应用程序角色以及它们在安装脚本中的使用方式。

关于安装脚本

安装脚本包含在如下上下文之一中运行 CREATE APPLICATION 命令时所运行的 SQL 语句:

  • 使用者安装或升级 Snowflake Native App。

  • A provider creates or upgrades an app when testing the application package.

备注

安装脚本仅支持使用 SQL 命令。不支持其他语言。

The SQL statements in the setup script create objects within the app that are required by the app. This includes database objects, stored procedures, views, and application roles.

The manifest file specifies the filename and relative path to the setup script. The setup script must exist on a named stage and be accessible by the app package.

安装脚本的限制

在安装脚本中无法执行以下操作:

  • USE DATABASE

  • USE SCHEMA

  • USE ROLE

  • USE SECONDARY ROLES

  • 使用 ALTER <object> 命令设置 LOG_LEVEL、TRACE_LEVEL 或 METRIC_LEVEL 属性。

  • 创建或调用 EXECUTE AS CALLER 过程。

  • 创建 Snowpark 用户定义的函数 (UDFs) 或在命名暂存区中使用 IMPORT 包含文件的过程。

  • 调用引用应用程序包中未包含的代码的过程、函数或匿名代码块。

  • 使用 CREATE FUNCTION 命令时从命名暂存区导入代码文件。

  • 使用 CALL 调用作为 EXECUTE AS CALLER 运行的过程。

在带有版本控制的架构中创建的对象还存在其他限制。

安装脚本中创建的对象的可见性

The setup script can create most types of database-level objects. Database objects created by the setup script are internal to the app. When a consumer installs an app, by default, these objects are invisible and inaccessible to the consumer account directly.

备注

提供商可在测试应用程序包时使用开发模式,访问由安装脚本创建的对象。有关更多信息,请参阅 使用开发、调试和会话调试模式测试应用程序

A provider can make these objects visible to the consumer using application roles. An application role created within the setup script is automatically granted to the role owning the app. Application roles granted by the setup script cannot be revoked.

Users that have been granted a role that owns the application object can grant application roles to other roles within their account. For example, the setup script can define an application role, such as APP_ADMIN, and this role can grant permission to access objects within the app.

设置安装脚本输出的消息的日志级别

提供商可为安装脚本运行时生成的消息指定日志级别。有关更多信息,请参阅 Snowflake Scripting 中的日志记录消息

要配置安装脚本的日志级别,请使用以下系统函数之一:

例如,要配置安装脚本以在日志中记录错误消息,请在安装脚本的开头添加以下命令:

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

创建模块化安装脚本

典型应用程序的安装脚本可能庞大而复杂。为了使安装脚本更加模块化且更易于维护,提供商可创建一个主安装脚本,并使该脚本调用多个辅助安装脚本。

例如,提供商可以创建不同的安装脚本来处理不同类型的任务,如创建对象、创建视图、创建存储过程等。

When the CREATE APPLICATION command runs, it runs the main setup script specified in the manifest file. To run additional setup scripts from the main setup script, use the EXECUTE IMMEDIATE FROM command.

主安装脚本中包含的安装脚本将按照遇到它们的顺序运行。这些辅助安装脚本还可以包含 EXECUTE IMMEDIATE FROM 命令的实例。

向应用程序添加多个安装脚本

  1. Add the location of the primary setup script to the manifest file.

    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 '../scripts/views/setup_views.sql';
    EXECUTE IMMEDIATE FROM '/scripts/data/setup_data.sql';
    ...
    
    Copy

    提供给 EXECUTE IMMEDIATE FROM 命令的路径区分大小写,且可以用于任何安装脚本。使用正斜杠 (/) 来表示应用程序根目录的相对路径,使用句点和正斜杠 (./) 来表示安装脚本的当前目录,使用两个句点和正斜杠 (../) 来表示安装脚本的父目录。

    主设置脚本是在清单中定义的脚本。EXECUTE IMMEDIATE FROM 命令可以与任何设置脚本一起使用。

在安装脚本中使用 EXECUTE IMMEDIATE FROM 时的限制

在安装脚本内使用 EXECUTE IMMEDIATE FROM 时,适用以下限制:

  • 使用 EXECUTE IMMEDIATE FROM 调用的安装脚本内不支持事件日志记录。

  • 不支持访问在使用者账户以外的加密外部暂存区上存储的文件。

  • 在应用程序运行时,只允许使用带有正斜杠 (/) 的相对路径格式。例如 EXECUTE IMMEDIATE FROM '/scripts/data/setup_data.sql'

创建安装脚本时遵循的最佳实践

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

Do not refer to objects in the app from outside the app

Do not create objects outside the app that refer to objects within the app. Although the Snowflake Native App Framework does not prohibit creating these objects, it can lead to problems when a consumer installs the Snowflake Native App.

For example, consider the context where a setup script creates a database, schema, and view outside of the app and the view refers to a table within the app. In this context, the view in the database breaks when the consumer takes ownership of the database and drops the 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.

如果策略分配触发了错误消息,则错误消息指定 POLICY 而非 TAG

要防止出现错误消息,请执行以下操作:

  • Snowflake Native App 提供商应更新设置脚本,确保在受版本控制的架构包含标签或设置了标签的对象时,在与标签相同的架构内的对象上设置标签(或策略)。如果非版本化架构包含标签或为其设置标签的对象,则无需更新设置脚本。

  • If the Snowflake Native App consumer sees this error message when installing an app, the consumer should ask the provider to update their setup script. Additionally, the consumer should not assign any tag that exists in a versioned schema to any object in their account, such as a warehouse, or assign a policy that exists in a versioned schema to a table or column, or assign a policy or tag to an object that exists in a versioned schema inside the Snowflake Native App. If so, Snowflake returns the same error message.

在受版本控制的架构中定义视图

始终在受版本控制的架构中定义共享内容的视图,以确保在升级期间访问视图的任何代码所使用的视图一致。在添加或删除新列或其他属性时,也应使用受版本控制的架构。

确保耗时的操作的兼容性

如果安装脚本必须执行非常长时间运行的操作,例如升级大型状态表,请确保这些更新与以前版本的现有运行代码兼容。

关于应用程序角色

By default the consumer has no privileges on objects created within the app. Even the ACCOUNTADMIN role cannot view the objects within an app. Objects that the app creates outside itself, such as a database, are visible only to the ACCOUNTADMIN role of the consumer account.

Application roles are similar to database roles, but may only be created within the app. Unlike database roles, application roles can be granted privileges on objects that exist outside of the app.

Application roles should be created by the setup script when the app is installed and are automatically granted to the app owner's role, who then can grant appropriate application roles to other roles in the consumer account.

备注

Application roles are the only type of role that can be created within an app. Database roles, for example, are not permitted within the app.

Likewise, application roles can only be created in an app and not, for example, in a normal database or at the account level.

Any privileges granted to application roles is passed to the app owner, which is the role used to install the app. The owner may further delegate application roles to other roles within the consumer account.

The setup script can also define an application role (e.g. USER). Using this role, consumers are granted access to use the functionality provided by the app. The setup script can define an application role, such as READ_ONLY, to provide restricted access to select areas of data within the app.

Unlike database roles, application roles may also be granted privileges on objects outside of the installed app. They may therefore be used to grant privileges on objects outside of the app. However, the application role itself must be created within the app.

支持与应用程序角色结合使用的 SQL 命令

Snowflake Native App Framework 提供以下与应用程序角色结合使用的 SQL 命令:

在安装脚本中使用应用程序角色

Application roles defined in the setup script are automatically granted to the role owning the app instance. When the app is installed, the role used to install the app is the owner of the app. However, the app owner can grant privileges to other account roles in the consumer account.

Application roles allow privileges on objects within the app to be granted to the consumer. For example:

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

In this example, the setup script creates application roles named admin and a user. The setup script then grants both application roles access to the schema containing the app code. It also grants access to the add function within the schema. The admin role is also granted access to the config_app procedure.

应用程序角色和版本

Application roles are not versioned. This means that dropping an application role or revoking a permission from an object that is not in a versioned schema can impact the current version of an application or the version being upgraded. Application roles may only be safely dropped when you have dropped all versions of the app that use those roles.

备注

不能向应用程序角色授予对象的所有权。这意味着安装脚本中定义的应用程序角色应该只用于允许使用者访问已安装的 Snowflake Native App 内的对象。

语言: 中文