예시 Python UDF
예시 Python UDF (Example Python UDFs)
Python 사용자 정의 함수에 대해 배운 뒤, 유효한 Python UDF 예시를 보여주는 문서예요. 인라인과 카탈로그 UDF에서 어떻게 쓰는지 차이를 중심으로 살펴봐요.
출처: 문서
본문
Python 사용자 정의 함수에 대해 배운 뒤, 다음 섹션들은 유효한 Python UDF 예시를 보여줘요.
UDF들은 이름과 예시 호출을 조정하면 인라인 사용자 정의 함수나 카탈로그 사용자 정의 함수로 모두 적합해요.
인라인 및 카탈로그 Python UDF
다음 섹션은 간단한 Python UDF 예시로 인라인과 카탈로그 UDF 사용의 차이를 보여줘요. 같은 패턴이 이후의 모든 섹션에 적용돼요.
입력 없이 정적 int 값 42를 반환하는 아주 간단한 Python UDF:
FUNCTION answer()
LANGUAGE PYTHON
RETURNS int
WITH (handler='theanswer')
AS $$
def theanswer():
return 42
$$
이 UDF를 인라인 UDF로 쓴 전체 예시와 문자열 연결에서 CAST와 함께 쓰는 예시:
WITH
FUNCTION answer()
RETURNS int
LANGUAGE PYTHON
WITH (handler='theanswer')
AS $$
def theanswer():
return 42
$$
SELECT 'The answer is ' || CAST(answer() as varchar);
-- The answer is 42
카탈로그 example이 default 스키마에서 UDF 저장을 지원한다면 다음을 사용할 수 있어요:
CREATE FUNCTION example.default.answer()
RETURNS int
LANGUAGE PYTHON
WITH (handler='theanswer')
AS $$
def theanswer():
return 42
$$;
UDF가 카탈로그에 저장되면, 재정의 없이 UDF를 여러 번 실행할 수 있어요:
SELECT example.default.answer() + 1; -- 43
SELECT 'The answer is ' || CAST(example.default.answer() as varchar); -- The answer is 42
또는 Config 속성에서 SQL PATH를 UDF 저장을 지원하는 카탈로그와 스키마로 구성할 수 있어요:
sql.default-function-catalog=example
sql.default-function-schema=default
sql.path=example.default
이제 전체 경로 없이 UDF를 관리할 수 있어요:
CREATE FUNCTION answer()
RETURNS int
LANGUAGE PYTHON
WITH (handler='theanswer')
AS $$
def theanswer():
return 42
$$;
UDF 호출도 전체 경로 없이 동작해요:
SELECT answer() + 5; -- 47
XOR
다음 예시는 두 boolean 입력 매개변수에 논리적 배타적 OR 연산을 수행하는 xor 함수를 구현하고 두 호출로 테스트해요:
WITH FUNCTION xor(a boolean, b boolean)
RETURNS boolean
LANGUAGE PYTHON
WITH (handler = 'bool_xor')
AS $$
import operator
def bool_xor(a, b):
return operator.xor(a, b)
$$
SELECT xor(true, false), xor(false, true);
쿼리 결과:
true | true
reverse_words
다음 예시는 varchar 타입 입력 문자열 s의 각 단어에서 문자를 뒤집는 더 정교한 Python 스크립트를 사용하고 함수를 테스트해요.
WITH FUNCTION reverse_words(s varchar)
RETURNS varchar
LANGUAGE PYTHON
WITH (handler = 'reverse_words')
AS $$
import re
def reverse(s):
str = ""
for i in s:
str = i + str
return str
pattern = re.compile(r"\w+[.,'!?\"]\w*")
def process_word(word):
# Reverse only words without non-letter signs
return word if pattern.match(word) else reverse(word)
def reverse_words(payload):
text_words = payload.split(' ')
return ' '.join([process_word(w) for w in text_words])
$$
SELECT reverse_words('Civic, level, dna racecar era semordnilap');
쿼리 결과:
Civic, level, and racecar are palindromes