애플리케이션 패키지에 애플리케이션 논리 추가하기

이 항목에서는 애플리케이션 패키지의 설정 스크립트에 애플리케이션 논리를 추가하는 방법을 설명합니다. 또한 애플리케이션 패키지에서 외부 코드 파일을 사용하는 방법도 설명합니다.

애플리케이션 패키지에 Streamlit 앱을 포함하는 방법에 대한 자세한 내용은 애플리케이션 패키지에 Streamlit 앱 추가하기 섹션을 참조하십시오.

저장 프로시저 및 함수 사용 시 고려 사항

Snowflake Native App Framework 를 사용하면 저장 프로시저, 사용자 정의 함수(UDF), 외부 함수를 애플리케이션 패키지에 포함할 수 있습니다. Snowflake에서 지원하는 언어 중 하나로 이들을 작성할 수 있습니다.

애플리케이션 코드를 안전하게 추가하기

모든 저장 프로시저와 Snowflake Native App 내 UDF는 애플리케이션으로 실행되고 설치된 Snowflake Native App 내의 모든 오브젝트에 액세스할 수 있습니다. 이는 SQL 주입 공격으로 이어질 수 있습니다.

Snowflake Native App 내에서 사용할 프로시저와 함수를 개발할 때 사용자의 입력이 필요한 모든 SQL 명령은 바인딩된 매개 변수를 사용하여 실행하는 것이 좋습니다. 여기에는 프로시저 인자를 통해 제공된 입력값이 포함됩니다.

자세한 내용은 저장 프로시저 만들기 섹션을 참조하십시오.

호출자의 권한과 소유자의 권한에 대한 설명

설정 스크립트로 생성되거나 설치된 Snowflake Native App 내에서 실행하는 프로시저는 모두 소유자의 권한(즉, EXECUTE AS OWNER)으로 실행해야 합니다.

Snowflake Native App 이 소유하지 않은 프로시저에서 호출자의 권한(EXECUTE AS CALLER)으로 Snowflake Native App 을 실행한 경우 프로시저는 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 이 소유한 저장 프로시저 및 UDF에서 차단됨(예외를 발생시킴).

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 라이브러리를 지원합니다.

외부 코드 파일 참조하기

애플리케이션 패키지에 포함할 수 있는 다음 두 가지 유형의 코드 파일이 있습니다.

  • 참조 파일: 바이너리, 라이브러리 및 기타 코드 파일을 포함합니다. 이러한 파일은 애플리케이션 패키지에 정의된 버전에 따라 다릅니다. 이러한 파일은 애플리케이션 패키지를 만들거나 애플리케이션 패키지에 버전을 추가할 때 스테이지의 루트 디렉터리에 있어야 합니다.

    참조된 파일은 애플리케이션 패키지의 설정 스크립트에 정의되어 있지 않으므로 사용자 정의 함수 및 저장 프로시저와 다릅니다. 이러한 파일은 설정 스크립트에 정의된 저장 프로시저와 UDF 내부의 import 문을 통해 참조됩니다.

  • 리소스 파일: 반정형 데이터, 정형 데이터, 바이너리(예: 머신 러닝 모델)를 포함합니다. 이러한 파일은 애플리케이션 패키지에 액세스할 수 있는 명명된 스테이지에 업로드해야 합니다.

이러한 유형의 코드 파일을 참조하는 저장 프로시저, 사용자 정의 함수 또는 외부 함수는 설정 스크립트에서 버전이 지정된 스키마 내에서 생성해야 합니다. 버전이 지정된 스키마 내에서 저장 프로시저 또는 함수를 생성할 때는 명명된 스테이지의 루트 디렉터리를 기준으로 코드 파일을 참조해야 합니다.

예를 들어 명명된 스테이지의 루트 디렉터리가 /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 UDF를 인라인으로 생성하기

Snowflake Native App Framework 는 JavaScala 를 포함하는 저장 프로시저 생성을 지원합니다. 저장 프로시저를 정의하는 코드를 설정 스크립트에 추가해야 합니다.

다음 예에서는 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 UDF 가져오기

미리 컴파일된 UDF를 생성하는 구문에서는 가져온 JAR을 버전이 지정된 아티팩트 세트의 일부로 포함해야 합니다. 미리 컴파일된 JAR을 참조하려면 IMPORT 절에서 전체 스테이지 위치를 지정하는 대신 상대 경로를 사용하십시오.

이 경로는 단일 슬래시로 시작하는 버전을 포함하는 루트 디렉터리에 상대적이어야 합니다(예: IMPORTS = ('/path/to/JARs/from/version/root')). 상대 경로에 대한 자세한 내용은 외부 코드 파일 참조하기 섹션을 참조하십시오.

다음은 코드 파일의 디렉터리 구조 예를 보여줍니다.

@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 UDF에 대한 제한 사항

Snowflake Native App Framework 는 Java와 Scala를 사용할 때 다음 제한 사항을 적용합니다.

  • 가져오기는 버전이 지정된 스키마에서 생성된 UDF에만 허용됩니다.

  • 가져오기 실행 시 상대 경로를 사용하여 버전 아티팩트에만 액세스할 수 있습니다.

  • 버전이 지정된 스키마 외부에서 생성된 UDF는 인라인으로만 생성할 수 있습니다.

  • 상대 경로는 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 UDF에 대한 제한 사항

Snowflake Native App Framework 는 Python UDF에 다음과 같은 제한 사항을 적용합니다.

  • 가져오기는 버전이 지정된 스키마에서 생성된 UDF에만 허용됩니다.

  • 가져오기 실행 시 상대 경로를 사용하여 버전 아티팩트에만 액세스할 수 있습니다.

  • 버전이 지정된 스키마 외부에서 생성된 UDF는 인라인으로만 생성할 수 있습니다.

애플리케이션 패키지에 JavaScript 함수 및 프로시저 추가하기

Snowflake Native App Framework 는 JavaScript API 를 사용하는 저장 프로시저와 사용자 정의 함수에서 JavaScript 사용을 지원합니다.

JavaScript 오류 처리하기

애플리케이션 패키지 내에서 JavaScript를 사용할 때는 오류를 포착하고 처리하는 것이 좋습니다. 그렇지 않으면 오류 메시지와 오류로 인해 반환되는 스택 추적이 컨슈머에게 표시됩니다. 데이터 콘텐츠와 애플리케이션 논리가 비공개로 유지되도록 하려면 중요한 오브젝트나 데이터에 액세스하는 상황에서 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 에 이 권한을 부여해야 합니다.