UDF에 대한 Python 언어 지원 - Amazon Redshift

UDF에 대한 Python 언어 지원

Python 프로그래밍 언어를 기반으로 사용자 지정 UDF를 생성할 수 있습니다. 다음 모듈을 제외하고, UDF에서 Python 2.7 Standard Library를 사용할 수 있습니다.

  • ScrolledText

  • Tix

  • Tkinter

  • tk

  • turtle

  • smtpd

다음 모듈은 Python Standard Library 외에 Amazon Redshift에도 구현되어 있습니다.

또한 사용자 지정 Python 모듈을 가져와서 UDF에서 CREATE LIBRARY 명령을 실행하는 데 사용할 수 있습니다. 자세한 내용은 사용자 지정 Python 라이브러리 모듈 가져오기 단원을 참조하십시오.

중요

Amazon Redshift는 UDF를 통해 파일 시스템에 접근하려는 모든 네트워크 액세스와 쓰기 액세스를 차단합니다.

참고

Python 3는 Python UDF에는 사용할 수 없습니다. Amazon Redshift UDF에 대한 Python 3 지원을 얻으려면 스칼라 Lambda UDF 생성을 사용하세요.

사용자 지정 Python 라이브러리 모듈 가져오기

스칼라 함수는 Python 언어 구문으로 정의됩니다. Python 표준 라이브러리 모듈과 Amazon Redshift 사전 설치된 모듈을 사용할 수 있습니다. 또한 사용자 정의 Python 라이브러리 모듈을 생성하고 라이브러리를 클러스터로 가져오거나 Python 또는 서드 파티의 기존 라이브러리를 사용할 수도 있습니다.

Python Standard Library 모듈 또는 Amazon Redshift에 사전 설치되어 있는 Python 모듈과 동일한 이름의 모듈이 포함되어 있는 라이브러리는 생성할 수 없습니다. 기존에 사용자가 설치한 라이브러리가 생성할 라이브러리와 동일한 Python 패키지를 사용하는 경우에는 기존 라이브러리를 삭제한 후 새로운 라이브러리를 설치해야 합니다.

사용자 지정 라이브러리를 설치하려면 수퍼유저이거나 USAGE ON LANGUAGE plpythonu 권한을 가지고 있어야 합니다. 하지만 함수를 생성할 수 있는 권한을 가진 사용자라면 누구나 설치된 라이브러리를 사용할 수 있습니다. 클러스터에 설치된 라이브러리 정보는 PG_LIBRARY 시스템 카탈로그에 대한 쿼리를 실행하여 확인할 수 있습니다.

사용자 지정 Python 모듈을 클러스터로 가져오려면

이번 단원에서는 사용자 지정 Python 모듈을 클러스터로 가져오는 예에 대해서 살펴봅니다. 이번 섹션에서 언급하는 단계를 따르려면 라이브러리 패키지를 업로드할 Amazon S3 버킷이 필요합니다. 업로드된 패키지는 클러스터에 설치됩니다. 버킷 생성에 대한 자세한 내용은 Amazon Simple Storage Service 사용 설명서버킷 생성을 참조하세요.

이번 예에서는 위치 및 거리 데이터를 가지고 작업할 UDF를 생성한다고 가정합니다. 먼저 SQL 클라이언트 도구에서 Amazon Redshift 클러스터에 연결한 후 다음 명령을 실행하여 함수를 생성합니다.

CREATE FUNCTION f_distance (x1 float, y1 float, x2 float, y2 float) RETURNS float IMMUTABLE as $$ def distance(x1, y1, x2, y2): import math return math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2) return distance(x1, y1, x2, y2) $$ LANGUAGE plpythonu; CREATE FUNCTION f_within_range (x1 float, y1 float, x2 float, y2 float) RETURNS bool IMMUTABLE as $$ def distance(x1, y1, x2, y2): import math return math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2) return distance(x1, y1, x2, y2) < 20 $$ LANGUAGE plpythonu;

위 예를 보면 일부 코드 라인이 중복되어 있습니다. UDF는 다른 UDF의 내용을 참조할 수 없을 뿐만 아니라 두 함수 모두 동일한 기능을 요구하기 때문에 이러한 중복은 필요합니다. 하지만 여러 함수에서 코드를 중복시킬 필요 없이 사용자 지정 라이브러리를 생성한 후 두 함수에서 사용하도록 구성하는 방법도 있습니다.

이를 위해서는 먼저 다음 단계에 따라 라이브러리 패키지를 생성해야 합니다.

  1. geometry라는 이름의 폴더를 생성합니다. 이 폴더는 라이브러리의 최상위 패키지입니다.

  2. geometry 폴더에서 __init__.py라는 이름의 파일을 생성합니다. 파일 이름을 보면 이중 밑줄 문자가 2개 포함되어 있습니다. 이 파일은 패키지가 초기화할 수 있다는 것을 Python에게 알려주는 역할을 합니다.

  3. 다시 한 번 geometry 폴더에서 trig라는 이름의 폴더를 생성합니다. 이 폴더는 라이브러리의 하위 패키지입니다.

  4. trig 폴더에서 __init__.py라는 이름의 파일을 한 번 더, 그리고 line.py라는 이름의 파일을 생성합니다. 이 폴더에서 __init__.py 파일은 하위 패키지가 초기화될 수 있다는 것을 Python에게 알려주는 역할을 하며, line.py는 라이브러리 코드가 저장되는 파일입니다.

    폴더 및 파일 구조는 다음과 같아야 합니다.

    geometry/ __init__.py trig/ __init__.py line.py

    패키지 구조에 대한 자세한 내용은 Python 웹사이트의 Python 튜토리얼에서 모듈 섹션을 참조하세요.

  5. 다음은 라이브러리의 클래스 및 멤버 함수가 포함된 코드입니다. 이 코드를 복사해서 line.py 파일에 붙여넣습니다.

    class LineSegment: def __init__(self, x1, y1, x2, y2): self.x1 = x1 self.y1 = y1 self.x2 = x2 self.y2 = y2 def angle(self): import math return math.atan2(self.y2 - self.y1, self.x2 - self.x1) def distance(self): import math return math.sqrt((self.y2 - self.y1) ** 2 + (self.x2 - self.x1) ** 2)

패키지 생성을 마쳤으면 이제 다음 단계에 따라 패키지를 준비하여 Amazon S3에 업로드합니다.

  1. geometry 폴더의 내용을 geometry.zip이라는 이름의 .zip 파일로 압축합니다. 이때 geometry 폴더 자체는 제외하고 다음과 같이 폴더의 내용만 압축 파일에 포함되어야 합니다.

    geometry.zip __init__.py trig/ __init__.py line.py
  2. geometry.zip을 Amazon S3 버킷에 업로드합니다.

    중요

    Amazon S3 버킷이 Amazon Redshift 클러스터와 동일한 리전에 속하지 않는 경우에는 REGION 옵션을 사용하여 데이터가 위치한 리전을 지정해야 합니다. 자세한 내용은 CREATE LIBRARY 단원을 참조하십시오.

  3. SQL 클라이언트 도구에서 다음 명령을 실행하여 라이브러리를 설치합니다. <bucket_name>은 버킷 이름으로, <access key id><secret key>는 각각 AWS Identity and Access Management(IAM) 사용자 자격 증명의 액세스 키와 비밀 액세스 키로 바꿉니다.

    CREATE LIBRARY geometry LANGUAGE plpythonu FROM 's3://<bucket_name>/geometry.zip' CREDENTIALS 'aws_access_key_id=<access key id>;aws_secret_access_key=<secret key>';

라이브러리를 클러스터에 설치한 후에는 라이브러리를 사용하도록 함수를 구성해야 합니다. 이를 위해 다음 명령을 실행합니다.

CREATE OR REPLACE FUNCTION f_distance (x1 float, y1 float, x2 float, y2 float) RETURNS float IMMUTABLE as $$ from trig.line import LineSegment return LineSegment(x1, y1, x2, y2).distance() $$ LANGUAGE plpythonu; CREATE OR REPLACE FUNCTION f_within_range (x1 float, y1 float, x2 float, y2 float) RETURNS bool IMMUTABLE as $$ from trig.line import LineSegment return LineSegment(x1, y1, x2, y2).distance() < 20 $$ LANGUAGE plpythonu;

위의 명령에서 import trig/line으로 이번 단원의 첫 번째 함수에서 보였던 중복 코드가 제거되었습니다. 이 라이브러리에서 제공하는 기능은 여러 UDF에서 재사용할 수 있습니다. 모듈을 가져오려면 하위 패키지 경로와 모듈 이름(trig/line)만 지정하면 됩니다.