为本地文件夹准备已配置的 Snowflake Native App 工件

创建一个本地文件夹,其中包含已配置的工件

snow app bundle 命令会在您的项目中创建一个本地目录,使用您在项目定义文件中指定的文件结构填充该目录,并从包含装饰器(如 @sproc@udaf)的 Snowpark Python 代码在 Snowflake Native App 安装脚本中生成 CREATE FUNCTION 或 CREATE PROCEDURE 声明。有关更多信息,请参阅与所选函数装饰器相对应的 Snowpark Python 文档,如 snowflake.snowpark.functions.udaf

snow app deploysnow app run 命令已经使用了这一功能。不过,现在有了明确的 snow app bundle 命令在手,您可以在上传到暂存区之前探索该目录,以验证是否按预期创建了工件。

要创建包含已配置工件的本地文件夹,请执行以下操作:

  1. 创建或验证您的 Snowflake snowflake.yml 项目定义文件,例如:

    definition_version: 2
    entities:
      codegen_nativeapp_pkg:
        type: application package
        manifest: root_files/_manifest.yml
        artifacts:
          - src: root_files/README.md
            dest: README.md
          - src: root_files/_manifest.yml
            dest: manifest.yml
          - src: root_files/setup_scripts/*
            dest: setup_scripts/
          - src: python/user_gen/echo.py
            dest: user_gen/echo.py
          - src: python/cli_gen/*
            dest: cli_gen/
            processors:
              - snowpark
      codegen_nativeapp_pkg:
        type: application
        from:
          target: codegen_nativeapp_pkg
    
    Copy
  2. 在项目目录下运行 snow app bundle 命令,创建包含已配置工件的临时 output/deploy 目录。

    snow app bundle
    
    Copy
  3. 验证输出或部署目录的内容是否符合您在 snowflake.yml. 文件中指定的规则。如果您在 Python 文件中调用了 Snowpark 注释处理,您可以在目录中的修正安装脚本中看到生成的代码。

有关更多信息,请参阅 snow app bundle 命令。

使用 Snowpark 注释处理生成 SQL 代码

作为 Snowflake Native App 开发人员,如果您的 SQL 背景有限,您可能会发现编写和维护 安装脚本 非常麻烦,随着时间的推移,脚本可能会变得相当庞大和复杂。安装脚本包含客户可使用其数据应用程序的所有应用逻辑,因此是开发 Snowflake Native App 的必要组成部分。安装脚本的核心组件之一是您可以将 Snowpark Python 扩展函数用于函数和存储过程。除了用 Python、Java 或其他 Snowpark 支持的语言编写 Snowpark 代码外,还需要在安装脚本中使用 SQL 编写这些函数和过程的相应部分。

例如,您可以使用 Snowpark Python 创建基本函数和存储过程,如下所示:

# Example python file "echo.py" that a developer writes

def echo_fn(data):
    return 'echo_fn: ' + data

def echo_proc(session, data):
    return 'echo_proc: ' + data
Copy

然后,您需要将该文件上传到暂存区,并从安装脚本 SQL 代码中引用该文件,类似于以下内容:

-- Sample setup_script.sql SQL file for a Snowflake Native App

CREATE APPLICATION ROLE IF NOT EXISTS app_instance_role;

CREATE OR ALTER VERSIONED SCHEMA ext_code_schema;
GRANT USAGE ON SCHEMA ext_code_schema TO APPLICATION ROLE app_instance_role;

CREATE OR REPLACE PROCEDURE ext_code_schema.py_echo_proc(DATA string)
  RETURNS STRING
  LANGUAGE PYTHON
  RUNTIME_VERSION = 3.9
  PACKAGES=('snowflake-snowpark-python')
  HANDLER='echo.echo_proc'
  IMPORTS=('/echo.py');

    GRANT USAGE ON PROCEDURE ext_code_schema.py_echo_proc(string)
      TO APPLICATION ROLE app_instance_role;

-- Wraps a function from a python file
CREATE OR REPLACE FUNCTION ext_code_schema.py_echo_fn(string)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
PACKAGES=('snowflake-snowpark-python')
HANDLER='echo.echo_fn'
IMPORTS=('/echo.py');

GRANT USAGE ON FUNCTION ext_code_schema.py_echo_fn(DATA string)
  TO APPLICATION ROLE app_instance_role;
Copy

SQL 代码自动生成

备注

要利用 SQL 代码自动生成功能,您必须使用 Snowpark Python 1.15.0 及以上版本。

为了帮助减轻这些额外的工作,Snowflake CLI 可以为您的安装脚本自动生成必要的 SQL。Snowpark Python 支持一种称为扩展函数装饰器(@udf@sproc@udtf@udaf)的功能,让您可以对 Python 代码进行注释,例如使用 snowflake.snowpark.functions.udf 函数装饰器。Snowflake CLI 可以使用这些装饰器为安装脚本自动创建和验证必要的 SQL 代码。

例如,您可以为上一个示例中的函数使用 @udf 装饰器:

# some python file echo.py
@udf(name="echo_fn")
def echo_fn(data) -> str:
  return 'echo_fn: ' + str
Copy

使用 @udf 装饰器会告诉 Snowflake CLI snow app bundle <../command-reference/native-apps-commands/bundle-app>`(以及其他内部调用 :codenowrap:`snow app bundle 命令的命令)处理 Snowpark Python 装饰器,生成相应的 SQL 命令,并将其自动包含在安装脚本中,如下所示。因此,您可以尽量减少安装脚本所需的 SQL 代码量。

-- Sample setup_script.sql SQL file for a Snowflake Native App

-- User-written code
CREATE OR REPLACE APPLICATION ROLE app_instance_role;

CREATE OR ALTER VERSIONED SCHEMA ext_code_schema;
GRANT USAGE ON SCHEMA ext_code_schema TO APPLICATION ROLE app_instance_role;

-- Snowflake CLI generated code
CREATE OR REPLACE FUNCTION ext_code_schema.py_echo_fn(DATA string)
  RETURNS STRING
  LANGUAGE PYTHON
  RUNTIME_VERSION = 3.9
  PACKAGES=('snowflake-snowpark-python')
  HANDLER='echo.echo_fn'
  IMPORTS=('/echo.py');

  GRANT USAGE ON FUNCTION ext_code_schema.py_echo_fn(string)
    TO APPLICATION ROLE app_instance_role;
Copy

使用 Snowpark Python 装饰器

虽然 Snowflake CLI 中的 Snowpark 装饰器与普通的 Snowpark Python 装饰器工作原理相同,但为 Snowflake Native App 专门编写 Python 代码文件时,您应该注意以下区别:

  • 您无法在这些文件中使用任何 Session 对象,因为 Snowflake CLI 是在与 Snowflake 无关的沙盒环境中执行这些 Python 文件的。因此,任何对 Snowpark Session 的引用都会导致错误。

  • 您只能使用 @udf@sproc @udaf@udtf Snowpark Python 装饰器。

  • 您无法将这些装饰器用作常规函数,以将您的代码注册为 Snowflake 对象。只有明确注释了支持的装饰器的代码才能被识别。因此,Python 函数必须是一个命名函数。不支持 Lambda 函数。

  • Snowflake CLI 始终会按照 Snowflake 的建议生成 CREATE OR REPLACE 语句,用于在安装脚本中创建函数和过程。

装饰器属性的更多信息

下表列出了 Python 装饰器属性,并解释了 Snowflake CLI 如何使用这些属性。

Python 装饰器属性

属性

详细信息

name

可选

用于生成 SQL 语句的函数或存储过程 Snowflake CLI 的名称。

如果省略此属性,Snowflake CLI 将重复使用 Python 函数名来生成 SQL 语句。

input_types

必填

此函数或存储过程的每个输入参数的类型。

您必须在此装饰器参数中提供此信息,或直接在代码中提供类型注释。如果这两个位置都没有该信息,Snowflake CLI 就不会为此函数或存储过程生成 SQL 语句。

return_type

必填

此函数或存储过程的返回值类型。

您必须在此装饰器参数中提供此信息,或直接在代码中提供类型注释。如果这两个位置都没有该信息,Snowflake CLI 就不会为此函数或存储过程生成 SQL 语句。

packages

可选

包列表。您可以指定 snowflake-snowpark-python,也可以不指定版本号。如果您为此包提供了版本号,Snowflake CLI 不会将该版本作为生成 SQL 的一部分,但会为列表中的任何其他包保留版本号。

如果省略此属性,Snowflake CLI 会自动添加 snowflake-snowpark-python 作为唯一包,并在生成的 SQL 语句中反映出来。

imports

可选

您的 Snowflake 函数或存储过程需要从暂存区导入的文件列表。您可以以字符串或字符串元组的形式指定它们。如果指定元组,Snowflake CLI 只使用第 0 个索引处的字符串。有关使用元组的示例,请参阅 使用外部 Python 文件

如果没有指定任何导入,Snowflake CLI 会自动为包含函数或存储过程的 Python 文件添加导入,并为其生成 SQL。导入路径由部署根目录中 Python 文件的 dest 参数根据项目定义文件确定。

execute_as

可选

执行存储过程时使用的角色。值包括:callerowner。 如果未指定,Snowflake CLI 默认为 owner。请注意,此属性不适用于函数。

handler

不适用

函数或存储过程的处理程序。Snowflake CLI 会自动填充此字段。

replace

未使用

Snowflake CLI 假定 true 用于代码生成。

session

必填

必须是 ``None``如果省略,Snowflake CLI 会引发错误。

is_permanent

未使用

生成 SQL 时,Snowflake CLI 不使用此字段。

stage_location

未使用

生成 SQL 时,Snowflake CLI 不使用此字段。

if_not_exists

未使用

生成 SQL 时,Snowflake CLI 不使用此字段。

strict

未使用

生成 SQL 时,Snowflake CLI 不使用此字段。

secure

未使用

生成 SQL 时,Snowflake CLI 不使用此字段。

immutable

未使用

生成 SQL 时,Snowflake CLI 不使用此字段。

native_app_params

可选

(仅适用于 Snowflake Native App)

包含以下 Snowflake Native App 参数的 Python 字典:

  • schema:包含 Snowpark 函数或存储过程的架构名称。此架构必须已在安装脚本中定义。Snowflake 建议在安装脚本文件中将该值设置为版本化架构的名称。在生成的 SQL 语句中,Snowflake CLI 会将此值作为 Snowpark 函数名称或存储过程名称的前缀。请注意,Snowflake CLI 不会为您创建架构。

  • application_roles:在生成的 Snowpark 函数或过程上授予 USAGE 权限的应用程序角色列表。Snowflake CLI 不会创建应用程序角色;它只会创建 SQL 语句,如 GRANT USAGE ON FUNCTION <schema_name.func_name> TO APPLICATION ROLE <app_role>,并将其添加到安装脚本中。

虽然在技术上是可选的,但如果不在项目定义文件中指定 native_app_params 属性,可能会导致安装脚本无效。

将 Python 文件上传到目标暂存区时,Snowflake CLI 会将装饰器转换为注释,因此这些 UDFs 和存储过程不会在当前会话中创建。原始源文件不会被更改,因此 snow app bundle 命令仍然具有幂等性。由于每次运行 snow app bundle 命令时都会重新创建部署根目录,因此只有部署根目录中的 Python 文件才会包含注释。下面的示例说明了 Snowflake CLI 如何对装饰器添加注释。

# output/deploy/dest_dir1/dest_dir2/echo.py
#: @sproc(
#:    return_type=IntegerType(),
#:    input_types=[IntegerType(), IntegerType()],
#:    packages=["snowflake-snowpark-python==1.15.0"],
#:    native_app_params={
#:        "schema": "ext_code_schema",
#:        "application_roles": ["app_instance_role"],
#:    },
#: )
def add_sp(session_, x, y):
    return x + y
Copy

此外,只有在项目定义文件中带有 processors 属性的 Python 文件才会受到影响。

语言: 中文