Snowpark(Python)에서 저장 프로시저 작성하기

이 항목에서는 Python에서 저장 프로시저를 작성하는 방법에 대해 설명합니다. 저장 프로시저 내에서 Snowpark 라이브러리를 사용하여 Snowflake의 테이블에 대한 쿼리, 업데이트 및 기타 작업을 수행할 수 있습니다.

이 항목의 내용:

소개

Snowpark 저장 프로시저를 사용하면 Snowflake 웨어하우스를 컴퓨팅 프레임워크로 사용하여 Snowflake 내에서 데이터 파이프라인을 구축하고 실행할 수 있습니다. 데이터 파이프라인 코드의 경우, Python용 Snowpark API를 사용하여 저장 프로시저를 작성합니다. 이러한 저장 프로시저의 실행을 예약하려면 작업 을 사용합니다.

머신 러닝 모델과 Snowpark Python에 대한 자세한 내용은 Snowpark Python으로 머신 러닝 모델 학습시키기 섹션을 참조하십시오.

다음 섹션에서는 Python용 Snowpark 저장 프로시저에 대한 자세한 정보를 제공합니다.

참고

익명 프로시저를 만들기도 하고 호출도 하려면 CALL(익명 프로시저 사용) 를 사용하십시오. 익명 프로시저를 만들고 호출하는 데는 CREATE PROCEDURE 스키마 권한이 있는 역할이 필요하지 않습니다.

전제 조건

버전 0.4.0 또는 최신 버전의 Snowpark 라이브러리를 사용해야 합니다.

Snowflake는 현재 Python 버전 3.8에서 저장 프로시저 작성을 지원합니다.

참고

Python 저장 프로시저에서는 서드 파티 종속 항목을 추가로 설치하는 최신 Snowpark Python 라이브러리가 필수적입니다. Python 저장 프로시저를 만들기 전, 필요한 서드 파티 종속 항목을 로딩할 수 있도록 Anaconda Packages 기능이 활성화되어 있는지 확인하십시오. 자세한 내용은 Anaconda의 서드 파티 패키지 사용하기 섹션을 참조하십시오.

Snowpark를 위한 개발 환경 설정

Snowpark 라이브러리를 사용하기 위한 개발 환경을 설정해야 합니다. 자세한 내용은 Snowpark를 위한 개발 환경 설정하기 를 참조하십시오.

인라인 코드 또는 스테이지에서 업로드된 코드를 사용하여 저장 프로시저를 만들도록 선택하기

Python UDF의 경우와 마찬가지로, 인라인 저장 프로시저 또는 스테이지에서 업로드된 코드로 저장 프로시저를 만들 수 있습니다.

  • 인라인 저장 프로시저에서 사용자는 CREATE PROCEDURE 문의 AS 절에 Python 코드를 작성합니다. 예:

    CREATE OR REPLACE PROCEDURE MYPROC(from_table STRING, to_table STRING, count INT)
      RETURNS STRING
      LANGUAGE PYTHON
      RUNTIME_VERSION = '3.8'
      PACKAGES = ('snowflake-snowpark-python')
      HANDLER = 'run'
    AS
    $$
    def run(session, from_table, to_table, count):
      session.table(from_table).limit(count).write.save_as_table(to_table)
      return "SUCCESS"
    $$;
    
  • 스테이지에서 업로드된 코드로 만든 저장 프로시저에서 .py 원본 파일에 Python 코드를 작성합니다. 예를 들어 다음 코드를 my_py_file.py 라는 파일에 넣을 수 있습니다.

    def run(session, from_table, to_table, count):
      session.table(from_table).limit(count).write.save_as_table(to_table)
      return "SUCCESS"
    

    그런 다음 파일을 스테이지에 업로드하고 스테이지의 파일을 가리키는 CREATE PROCEDURE 명령을 실행합니다. 예:

    CREATE OR REPLACE PROCEDURE MYPROC(from_table STRING, to_table STRING, count INT)
      RETURNS INT
      LANGUAGE PYTHON
      RUNTIME_VERSION = '3.8'
      PACKAGES = ('snowflake-snowpark-python')
      IMPORTS = ('@mystage/my_py_file.py')
      HANDLER = 'my_py_file.run';
    

저장 프로시저에 대한 Python 코드 작성하기

저장 프로시저에 대한 코드의 경우 Python 메서드 또는 함수를 작성해야 합니다.

저장 프로시저 작성 계획하기

아래의 설명과 같이, 저장 프로시저에 대한 Python 코드에는 Python UDF에 대한 코드와 동일한 제약 조건이 있습니다. 저장 프로시저 작성을 계획할 때 이러한 제약 조건을 고려해야 합니다.

사용되는 메모리 양 제한

Python UDF 의 경우와 마찬가지로 Snowflake는 필요한 메모리 양 측면에서 메서드 또는 함수에 제한을 둡니다.

메서드나 함수에서 너무 많은 메모리를 사용하지 않아야 합니다.

스레드로부터 안전한 코드 작성하기

유사하게, Python UDF의 경우와 마찬가지로 메서드 또는 함수가 스레드로부터 안전한지 확인해야 합니다.

보안 제한 이해하기

메서드 또는 함수는 제한된 엔진 내에서 실행되므로 Python UDF에 대해 문서화된 것과 동일한 규칙을 따라야 합니다.

소유자의 권한 또는 호출자의 권한 사용 결정하기

또한, 저장 프로시저를 작성하려고 계획할 때 저장 프로시저를 호출자의 권한으로 실행할지 소유자의 권한으로 실행할지 여부를 고려하십시오.

snowflake-snowpark-python 버전에 유의

Python 저장 프로시저 환경에서 사용할 수 있는 snowflake-snowpark-python 라이브러리는 보통 공개적으로 출시된 버전보다 한 버전 뒤처진 버전입니다. 이는 저장 프로시저 릴리스 프로세스의 제한 사항 때문입니다. 이 SQL을 사용하여 사용 가능한 최신 snowflake-snowpark-python 버전을 찾습니다.

select * from information_schema.packages where package_name = 'snowflake-snowpark-python' order by version desc;

메서드 또는 함수 작성하기

저장 프로시저에 대한 메서드 또는 함수를 작성할 때 다음 사항에 유의하십시오.

  • Snowpark Session 오브젝트를 메서드 또는 함수의 첫 번째 인자로 지정합니다. 저장 프로시저를 호출하면 Snowflake는 자동으로 Session 오브젝트를 생성하여 저장 프로시저에 전달합니다. (Session Session 오브젝트를 직접 만들 수는 없습니다.)

  • 나머지 인자와 반환 값의 경우, Snowflake 데이터 타입 에 해당하는 Python 타입을 사용합니다. Snowflake는 매개 변수 및 반환 형식에 대한 SQL-Python 데이터 타입 매핑 에 나열된 Python 데이터 타입을 지원합니다.

저장 프로시저에서 Snowflake의 데이터에 액세스하기

Snowflake의 데이터에 액세스하려면 Snowpark 라이브러리 API를 사용합니다.

Python 저장 프로시저에 대한 호출을 처리할 때 Snowflake는 Snowpark Session 오브젝트를 생성하고 저장 프로시저에 대한 메서드나 함수에 오브젝트를 전달합니다.

다른 언어의 저장 프로시저의 경우와 마찬가지로 세션의 컨텍스트(예: 권한, 현재 데이터베이스, 스키마 등)는 저장 프로시저가 호출자의 권한으로 실행되는지 소유자의 권한으로 실행되는지에 따라 결정됩니다. 자세한 내용은 세션 상태 액세스 및 설정하기 섹션을 참조하십시오.

Session 오브젝트를 사용하여 Snowpark 라이브러리 에서 API를 호출할 수 있습니다. 예를 들어 테이블에 대한 DataFrame을 만들거나 SQL 문을 실행할 수 있습니다.

자세한 내용은 Snowpark 개발자 가이드 를 참조하십시오.

다음은 지정된 수의 행을 한 테이블에서 다른 테이블로 복사하는 Python 메서드의 예입니다. 이 메서드는 다음 인자를 사용합니다.

  • Snowpark Session 오브젝트

  • 행을 복사할 출처가 되는 테이블의 이름

  • 행이 저장될 테이블의 이름

  • 복사할 행의 수

이 예의 메서드는 문자열을 반환합니다.

def run(session, from_table, to_table, count):

session.table(from_table).limit(count).write.save_as_table(to_table)
  return "SUCCESS"

Anaconda의 서드 파티 패키지 사용하기

Python 저장 프로시저를 만들 때 설치할 Anaconda 패키지를 지정할 수 있습니다. Anaconda의 서드 파티 패키지 목록을 보려면 Anaconda Snowflake 채널 을 참조하십시오. 이러한 서드 파티 패키지는 Anaconda에서 만들어 제공합니다. Anaconda의 서비스 약관에 대한 추가 포함 소프트웨어 약관에 따라 현지 테스트 및 개발을 위한 Snowflake conda 채널을 무료로 사용할 수 있습니다.

제한 사항은 제한 사항 섹션을 참조하십시오.

시작하기

Snowflake 내부에서 Anaconda가 제공하는 패키지를 사용하기 시작하기 전, 아래 단계를 따라 Snowflake 서드 파티 약관 에 동의해야 합니다.

참고

  • 이 섹션의 단계를 완료하려면 조직 관리자(ORGADMIN) 역할이 필요합니다. 조직에 대한 자세한 내용은 Snowflake 조직 관리하기 를 참조하십시오.

  • 약관에 동의하려면 사용자는 다음 사용자 속성 을 설정해야 합니다.

    • 이름

    • 이메일 주소


    사용자 속성이 설정되지 않은 경우 Snowflake UI는 이러한 속성을 업데이트하라는 메시지를 표시한 후 계속 진행합니다. 사용자 관리자(즉, USERADMIN 역할이 있는 사용자) 또는 더 높은 역할이나, Snowflake 사용자 오브젝트에 대한 OWNERSHIP 권한이 있는 다른 역할은 이러한 세부 정보를 귀하의 사용자 프로필 에 추가할 수 있습니다.

  1. Snowflake 웹 인터페이스인 Snowsight 에 로그인합니다.

  2. 로그인 이름 옆에 있는 드롭다운 메뉴를 클릭한 다음 Switch Role » ORGADMIN 을 클릭하여 조직 관리자 역할로 변경합니다.

  3. Admin » Billing » Terms & Billing 를 클릭합니다.

  4. Anaconda 섹션으로 스크롤하고 Enable 버튼을 클릭합니다. Anaconda Packages (Preview Feature) 대화 상자가 열립니다.

  5. 링크를 클릭하여 Snowflake 서드 파티 약관을 검토하십시오.

  6. 약관에 동의하면 Acknowledge & Continue 버튼을 클릭합니다.

참고

위에 설명된 대로 Snowflake 서드 파티 약관에 동의하지 않더라도 저장 프로시저를 계속 사용할 수 있지만, 다음과 같은 제한 사항이 따릅니다.

  • Anaconda의 서드 파티 패키지는 사용할 수 없습니다.

  • Snowpark Python을 저장 프로시저의 패키지로 계속 지정할 수 있지만, 특정 버전을 지정할 수는 없습니다.

  • DataFrame 오브젝트와 상호 작용할 때는 to_pandas 메서드를 사용할 수 없습니다.

패키지 표시 및 사용하기

또한 Information Schema에서 PACKAGES 뷰를 쿼리하여 사용 가능한 모든 패키지와 해당 버전 정보를 표시할 수도 있습니다.

select * from information_schema.packages where language = 'python';

자세한 내용은 Snowflake Python UDF 설명서에서 서드 파티 패키지 사용 을 참조하십시오.

다른 클래스 및 리소스 파일에 액세스하기

코드가 저장 프로시저 외부에 정의된 다른 리소스 파일 또는 Python 모듈에 의존하는 경우, 저장 프로시저가 실행될 때 파일을 사용할 수 있도록 해당 파일을 스테이지에 업로드 해야 합니다.

나중에 CREATE PROCEDURE 문을 실행 할 때 IMPORTS 절을 사용하여 이러한 파일을 가리킵니다.

스테이지에 파일 업로드하기

저장 프로시저에 필요한 파일을 스테이지에 업로드합니다.

  1. 파일의 스테이지를 선택합니다.

    외부 또는 명명된 내부 스테이지를 사용할 수 있습니다. PUT 명령을 사용하여 파일을 업로드하려는 계획인 경우, 명명된 내부 스테이지를 사용합니다. (PUT 명령은 외부 스테이지에 파일을 업로드하는 것을 지원하지 않습니다.)

    기존 스테이지를 사용하거나 CREATE STAGE 를 실행하여 새 스테이지를 생성할 수 있습니다. 예를 들어 다음 명령은 mystage 라는 새 내부 스테이지를 만듭니다.

    CREATE STAGE mystage;
    

    참고

    저장 프로시저의 소유자는 스테이지에 대한 READ 권한 이 있어야 합니다.

  2. PUT 명령을 사용하여 해당 스테이지에 다음 파일을 업로드합니다.

    • Python 코드를 포함하는 파일.

    • 저장 프로시저가 의존하는 다른 모든 파일.

    예:

    put file:///users/myusername/myfile.py
            @mystage
            AUTO_COMPRESS = FALSE
            OVERWRITE = TRUE
            ;
    

    참고

    AUTO_COMPRESS = FALSE 를 생략하면 PUT 명령이 자동으로 파일을 압축합니다. 스테이지의 압축 파일 이름은 myfile.py.gz 가 됩니다. 나중에 CREATE PROCEDURE 명령을 실행 할 때 사용자는 IMPORTS 절에서 이 .gz 확장자를 가진 파일 이름을 지정해야 합니다.

    참고

    PUT 명령은 외부 스테이지에 파일을 업로드하는 것을 지원하지 않습니다. 외부 스테이지로 파일을 업로드하려면 클라우드 서비스에서 제공하는 유틸리티를 사용하십시오.

Python 코드가 포함된 파일을 삭제하거나 이름을 바꾸면 더 이상 저장 프로시저를 호출할 수 없습니다.

파일을 업데이트해야 하는 경우:

  • 저장 프로시저를 호출할 수 없는 동안 업데이트합니다.

  • PUT 명령에 OVERWRITE=TRUE 절을 추가합니다.

저장 프로시저 만들기

CREATE PROCEDURE 문을 실행하여 메서드나 함수에 대한 저장 프로시저를 만듭니다.

참고

익명 프로시저를 만들기도 하고 호출도 하려면 CALL(익명 프로시저 사용) 를 사용하십시오. 익명 프로시저를 만들고 호출하는 데는 CREATE PROCEDURE 스키마 권한이 있는 역할이 필요하지 않습니다.

아래 표에 나열된 대로 CREATE PROCEDURE 매개 변수를 설정합니다.

매개 변수

설명

[ arg_name arg_data_type [, ... ] ]

  • Snowpark Session 오브젝트에 대한 인자를 생략합니다. 앞서 언급했듯이 이는 CREATE PROCEDURE 또는 CALL에서 지정하는 형식 매개 변수가 아닙니다. 저장 프로시저를 호출하면 Snowflake는 Session 오브젝트를 생성하여 저장 프로시저에 전달합니다.

  • 나머지 인자의 데이터 타입의 경우, 메서드 또는 함수에 있는 인자의 Python 타입 에 해당하는 Snowflake 데이터 타입 을 사용합니다.

RETURNS result_data_type

반환 값의 Snowflake 데이터 타입으로 RETURNS를 지정합니다.

LANGUAGE PYTHON

저장 프로시저 코드가 Python으로 작성되었음을 나타내려면 이를 지정해야 합니다.

RUNTIME_VERSION = '3.8'

저장 프로시저가 Python 3.8을 사용함을 나타내려면 이를 지정해야 합니다.

PACKAGES = ( 'package_name' )

이 목록에서, 사용하려는 Snowpark 라이브러리 버전에 대한 패키지를 포함합니다.

Snowpark 라이브러리의 정규화된 패키지 이름을 다음 형식으로 지정합니다.

snowflake-snowpark-python==<version>

예:

  • 최신 버전의 Snowpark를 사용하려면 다음을 사용합니다.

    PACKAGES = ('snowflake-snowpark-python')
    
  • 0.4.0 버전의 Snowpark를 사용하려면 다음을 사용합니다.

    PACKAGES = ('snowflake-snowpark-python==0.4.0')
    

IMPORTS = ( 'file' [, 'file' ... ] )

인라인 저장 프로시저를 작성하는 경우, 코드가 저장 프로시저 또는 리소스 파일 외부에 정의된 클래스에 종속되지 않는 한 이 절을 생략할 수 있습니다.

스테이지에서 업로드된 코드로 저장 프로시저를 만드는 경우 이 목록에 해당 파일을 포함하십시오.

스테이지 위치 에 업로드한 파일에 저장 프로시저가 의존하는 경우 이 목록에 해당 파일을 포함합니다.

HANDLER = 'method_name'

이를 Python 메서드 또는 함수의 정규화된 이름으로 설정합니다.

EXECUTE AS CALLER

호출자의 권한 을 사용하도록 저장 프로시저를 설정하려는 계획인 경우 이 매개 변수를 추가합니다.

그렇지 않은 경우, 소유자 권한을 사용하려면 이 매개 변수를 생략합니다.

다음 예에서는 Python에서 저장 프로시저를 만듭니다.

예 1: 인라인 저장 프로시저:

CREATE OR REPLACE PROCEDURE myProc(from_table STRING, to_table STRING, count INT)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'run'
AS
$$
def run(session, from_table, to_table, count):
  session.table(from_table).limit(count).write.save_as_table(to_table)
  return "SUCCESS"
$$;

예 2: 내부 스테이지 mystage 의 Python 파일 myfile.py 의 스테이지에서 업로드된 코드를 사용하는 저장 프로시저:

CREATE OR REPLACE PROCEDURE myProc(from_table STRING, to_table STRING, count INT)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
IMPORTS = ('@mystage/myfile.py')
HANDLER = 'myfile.run'

테이블 형식 데이터 반환하기

Snowpark 데이터 프레임을 사용하여 Python 저장 프로시저에서 테이블 형식 데이터를 반환하려면 CREATE PROCEDURE 문에 RETURNS TABLE(...) 을 지정합니다.

반환된 테이블에 있는 열의 Snowflake 데이터 타입 을 알면 RETURNS TABLE() 문에서 열 이름과 유형을 지정하십시오. 그렇지 않으면(예: 런타임 중에 열 유형을 결정하는 경우) 열 이름과 유형을 생략할 수 있습니다.

다음은 직원 테이블을 만든 다음 저장 프로시저를 사용하여 열이 문자열과 일치하는 행을 필터링하는 예입니다.

CREATE OR REPLACE TABLE employees(id NUMBER, name VARCHAR, role VARCHAR);
INSERT INTO employees (id, name, role) VALUES (1, 'Alice', 'op'), (2, 'Bob', 'dev'), (3, 'Cindy', 'dev');

다음 코드는 테이블 이름과 역할을 인자로 사용하고 역할이 지정된 역할과 일치하는 테이블의 행을 반환하는 저장 프로시저를 만듭니다. 반환 열과 각 열의 데이터 타입을 알고 있으므로 프로시저를 만들 때 RETURNS TABLE() 문에 이를 지정합니다.

CREATE OR REPLACE PROCEDURE filterByRole(tableName VARCHAR, role VARCHAR)
RETURNS TABLE(id NUMBER, name VARCHAR, role VARCHAR)
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'filter_by_role'
AS
$$
from snowflake.snowpark.functions import col

def filter_by_role(session, table_name, role):
   df = session.table(table_name)
   return df.filter(col("role") == role)
$$;

또는 런타임에 열 유형을 결정하는 경우 RETURNS TABLE() 문에서 열 이름과 유형을 생략할 수 있습니다.

CREATE OR REPLACE PROCEDURE filterByRole(tableName VARCHAR, role VARCHAR)
RETURNS TABLE()
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'filter_by_role'
AS
$$
from snowflake.snowpark.functions import col

def filter_by_role(session, table_name, role):
  df = session.table(table_name)
  return df.filter(col("role") == role)
$$;

다음 예에서는 저장 프로시저를 호출합니다.

CALL filterByRole('employees', 'dev');
>>     +----+-------+------+
       | ID | NAME  | ROLE |
       +----+-------+------+
       | 2  | Bob   | dev  |
       | 3  | Cindy | dev  |
       +----+-------+------+

참고

현재, CREATE PROCEDURERETURNS TABLE(...) 절에서는 GEOGRAPHY를 열 유형으로 지정할 수 없습니다.

CREATE OR REPLACE PROCEDURE test_return_geography_table_1()
RETURNS TABLE(g GEOGRAPHY)
...

그렇게 할 경우 저장 프로시저를 호출하면 오류가 발생합니다.

CALL test_return_geography_table_1();
Stored procedure execution error: data type of returned table does not match expected returned table type

이 문제를 해결하려면 RETURNS TABLE() 에서 열 인자와 유형을 생략하면 됩니다.

CREATE OR REPLACE PROCEDURE test_return_geography_table_1()
RETURNS TABLE()
...

저장 프로시저 호출하기

사용자가 저장 프로시저를 호출하려면 사용자의 역할에 저장 프로시저에 대한 USAGE 권한 이 있어야 합니다.

저장 프로시저를 호출할 권한이 있으면 CALL 문을 사용하여 저장 프로시저를 호출할 수 있습니다. 예:

CALL myProc('table_a', 'table_b', 5);

제한 사항

Snowpark 저장 프로시저에는 다음과 같은 제한 사항이 있습니다.

  • 저장 프로시저에서는 프로세스 생성이 지원되지 않습니다.

  • 명명된 임시 오브젝트 만들기는 소유자의 권한 저장 프로시저에서 지원되지 않습니다. 소유자의 권한 저장 프로시저는 저장 프로시저 소유자의 권한으로 실행되는 저장 프로시저입니다. 자세한 내용은 호출자 권한 또는 소유자 권한 을 참조하십시오.

  • 저장 프로시저에서는 동시 쿼리 실행이 지원되지 않습니다.

  • 작업에서 저장 프로시저를 실행하는 경우, 작업을 만들 때 웨어하우스를 지정해야 합니다. (사용자는 Snowflake가 관리하는 컴퓨팅 리소스를 사용하여 작업을 실행할 수 없습니다.)

  • PUT 및 GET 명령을 실행하는 API(Session.sql("PUT ...")Session.sql("GET ...") 포함)를 사용할 수 없습니다.

  • session.file.get 을 사용하여 스테이지에서 파일을 다운로드할 때는 패턴 일치가 지원되지 않습니다.

  • Python UDF 또는 저장 프로시저에서 joblib.Parallel 을 사용할 때 backend 매개 변수를 threading 으로 설정해야 합니다. 자세한 내용은 서드 파티 패키지 사용에 대한 설명서 를 참조하십시오.

맨 위로 이동