Python UDF ๋ง๋ค๊ธฐยถ
์ด ํญ๋ชฉ์์๋ Python UDF(์ฌ์ฉ์ ์ ์ ํจ์)๋ฅผ ๋ง๋ค๊ณ ์ค์นํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
์ด ํญ๋ชฉ์ ๋ด์ฉ:
Python ์ฝ๋ ์ฐ๊ธฐยถ
Python ๋ชจ๋ ๋ฐ ํจ์ ์ฐ๊ธฐยถ
์๋ ์ฌ์์ ๋ฐ๋ฅด๋ ๋ชจ๋์ ์ฐ์ญ์์ค.
๋ชจ๋์ ์ ์ํฉ๋๋ค. ๋ชจ๋์ Python ์ ์ ๋ฐ ๋ฌธ์ ํฌํจํ๋ ํ์ผ์ ๋๋ค.
๋ชจ๋ ๋ด๋ถ์ ํจ์๋ฅผ ์ ์ํฉ๋๋ค.
ํจ์๊ฐ ์ธ์๋ฅผ ํ์ฉํ๋ ๊ฒฝ์ฐ, ๊ฐ ์ธ์๋ SQL-Python ํ์ ๋งคํ ํ ์ด๋ธ ์
Python Data Type
์ด์ ์ง์ ๋ ๋ฐ์ดํฐ ํ์ ์ค ํ๋์ฌ์ผ ํฉ๋๋ค.ํจ์ ์ธ์๋ ์ด๋ฆ์ด ์๋ ์์น๋ก ๋ฐ์ธ๋ฉ๋ฉ๋๋ค. UDF์ ์ ๋ฌ๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ Python ํจ์์์ ์์ ํ ์ฒซ ๋ฒ์งธ ์ธ์์ ๋๋ค.
์ ์ ํ ๋ฐํ ๊ฐ์ ์ง์ ํ์ญ์์ค. Python UDF๋ ์ค์นผ๋ผ ํจ์์ฌ์ผ ํ๋ฏ๋ก ํธ์ถ๋ ๋๋ง๋ค ํ๋์ ๊ฐ์ ๋ฐํํด์ผ ํฉ๋๋ค. ๋ฐํ ๊ฐ์ ํ์์ SQL-Python ํ์ ๋งคํ ํ ์ด๋ธ ์
Python Data Type
์ด์ ์ง์ ๋ ๋ฐ์ดํฐ ํ์ ์ค ํ๋์ฌ์ผ ํฉ๋๋ค. ๋ฐํ ๊ฐ์ ํ์์ CREATE FUNCTION ๋ฌธ์RETURNS
์ ์ ์ง์ ๋ SQL ๋ฐ์ดํฐ ํ์ ๊ณผ ํธํ๋์ด์ผ ํฉ๋๋ค.๋ชจ๋์๋ ๋ ์ด์์ ํจ์๊ฐ ํฌํจ๋ ์ ์์ต๋๋ค. Snowflake์์ ํธ์ถํ๋ ํจ์๋ ๋์ผํ ๋ชจ๋์ ๋ค๋ฅธ ํจ์ ๋๋ ๋ค๋ฅธ ๋ชจ๋์ ๋ค๋ฅธ ํจ์๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
ํจ์(๋ฐ ํด๋น ํจ์์์ ํธ์ถํ๋ ๋ชจ๋ ํจ์)๋ Python UDF์ ๋ํด Snowflake๊ฐ ๋ถ๊ณผํ ์ ์ฝ ์กฐ๊ฑด ์ ์ค์ํด์ผ ํฉ๋๋ค.
์ฐธ๊ณ
๋ฒกํฐํ๋ Python UDF๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋ ฅ ํ ๋ฐฐ์น๋ฅผ Pandas DataFrames ๋ก ์์ ํ๊ณ ๊ฒฐ๊ณผ ๋ฐฐ์น๋ฅผ Pandas ๋ฐฐ์ด ๋๋ Series ๋ก ๋ฐํํ๋ Python ํจ์๋ฅผ ์ ์ํ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ๋ฒกํฐํ๋ Python UDF ์น์ ์ ์ฐธ์กฐํ์ญ์์ค.
Snowflake์์ ํจ์ ๋ง๋ค๊ธฐยถ
๋ค์์ ์ง์ ํ๋ ค๋ฉด CREATE FUNCTION ๋ฌธ์ ์คํํด์ผ ํฉ๋๋ค.
UDF์ ์ฌ์ฉํ ์ด๋ฆ์ ๋๋ค.
Python UDF๊ฐ ํธ์ถ๋ ๋ ํธ์ถํ Python ํจ์์ ์ด๋ฆ์ ๋๋ค.
UDF์ ์ด๋ฆ์ Python์ผ๋ก ์์ฑ๋ ํธ๋ค๋ฌ ํจ์์ ์ด๋ฆ๊ณผ ์ผ์นํ ํ์๊ฐ ์์ต๋๋ค. CREATE FUNCTION ๋ฌธ์ HANDLER ์ ์ UDF ์ด๋ฆ์ Python ํจ์์ ์ฐ๊ด์ํต๋๋ค.
UDF์ ์ด๋ฆ์ ์ ํํ ๋ ํ๋ก์์ ์ UDF์ ๋ช ๋ช ๋ฐ ์ค๋ฒ๋ก๋ฉ ์น์ ์ ์ฐธ์กฐํ์ญ์์ค.
CREATE FUNCTION ๋ฌธ์ ๋ณธ๋ฌธ ๋ด์์ ํจ์ ์ธ์๋ ์ด๋ฆ์ด ์๋ ์์น๋ก ๋ฐ์ธ๋ฉ๋ฉ๋๋ค. CREATE FUNCTION ๋ฌธ์์ ์ ์ธ๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ Python ํจ์์ ์ ๋ฌ๋ ์ฒซ ๋ฒ์งธ ์ธ์์ ๋๋ค.
์ธ์์ ๋ฐ์ดํฐ ํ์ ์ ๋ํ ์์ธํ ๋ด์ฉ์ SQL-Python ๋ฐ์ดํฐ ํ์ ๋งคํ ์ ์ฐธ์กฐํ์ญ์์ค.
runtime_version
์ ์ฝ๋์์ ํ์ํ Python ๋ฐํ์ ๋ฒ์ ์ผ๋ก ์ค์ ํฉ๋๋ค. ์ง์๋๋ Python ๋ฒ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
3.9
3.10
3.11
3.12
์ธ๋ผ์ธ ์ฝ๋๊ฐ ์๋ UDFs์ ์คํ ์ด์ง์์ ์ ๋ก๋๋ ์ฝ๋๊ฐ ์๋ UDFsยถ
Python UDF์ ๋ํ ์ฝ๋๋ ๋ค์ ๋ฐฉ๋ฒ ์ค ํ๋๋ก ์ง์ ํ ์ ์์ต๋๋ค.
์คํ ์ด์ง์์ ์ ๋ก๋๋จ: CREATE FUNCTION ๋ฌธ์ ์คํ ์ด์ง ์์ ๊ธฐ์กด Python ์์ค ์ฝ๋์ ์์น๋ฅผ ์ง์ ํฉ๋๋ค.
์ธ๋ผ์ธ: CREATE FUNCTION ๋ฌธ์ Python ์์ค ์ฝ๋๋ฅผ ์ง์ ํฉ๋๋ค.
์ธ๋ผ์ธ Python UDF ๋ง๋ค๊ธฐยถ
์ธ๋ผ์ธ UDF์ ๊ฒฝ์ฐ, CREATE FUNCTION ๋ฌธ์ ์ผ๋ถ๋ก์ Python ์์ค ์ฝ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ค์ ๋ฌธ์ ์ฃผ์ด์ง ์ ์์ 1์ ๋ํ๋ ์ธ๋ผ์ธ Python UDF๋ฅผ ์์ฑํฉ๋๋ค.
CREATE OR REPLACE FUNCTION addone(i INT)
RETURNS INT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
HANDLER = 'addone_py'
AS $$
def addone_py(i):
return i+1
$$;
Python ์์ค ์ฝ๋๋ AS
์ ์ ์ง์ ๋ฉ๋๋ค. ์์ค ์ฝ๋๋ ์์๋ฐ์ดํ๋ ํ ์์ ๋ฌ๋ฌ ๊ธฐํธ($$
)๋ก ๋ฌถ์ ์ ์์ต๋๋ค. ์์ค ์ฝ๋์ ์์๋ฐ์ดํ๊ฐ ํฌํจ๋์ด ์๋ ๊ฒฝ์ฐ, ์ผ๋ฐ์ ์ผ๋ก ์ด์ค ๋ฌ๋ฌ ๊ธฐํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ฝ์ต๋๋ค.
UDF๋ฅผ ํธ์ถํฉ๋๋ค.
SELECT addone(10);
์ถ๋ ฅ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
+------------+
| ADDONE(10) |
|------------|
| 11 |
+------------+
Python ์์ค ์ฝ๋๋ ๋ ์ด์์ ๋ชจ๋, ๊ทธ๋ฆฌ๊ณ ํ ๋ชจ๋์ ๋ ์ด์์ ํจ์๋ฅผ ํฌํจํ ์ ์์ผ๋ฏ๋ก HANDLER
์ ์ ํธ์ถํ ๋ชจ๋๊ณผ ํจ์๋ฅผ ์ง์ ํฉ๋๋ค.
์ธ๋ผ์ธ Python UDF๋ IMPORTS
์ ์ ํฌํจ๋ ๋ชจ๋์ ์ฝ๋๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
CREATE FUNCTION ๋ฌธ์ ๊ตฌ๋ฌธ์ ๋ํ ์์ธํ ๋ด์ฉ์ CREATE FUNCTION ์ ์ฐธ์กฐํ์ญ์์ค.
๋ ๋ง์ ์์ ๋ ์ธ๋ผ์ธ Python UDF ์์ ๋ฅผ ์ฐธ์กฐํ์ญ์์ค.
์คํ ์ด์ง์์ ์ ๋ก๋๋ ์ฝ๋๋ก Python UDF ๋ง๋ค๊ธฐยถ
๋ค์ ๋ฌธ์ ์คํ ์ด์ง ์์ ์ ๋ก๋๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ Python UDF๋ฅผ ๋ง๋ญ๋๋ค. ํ์ผ์ ํธ์คํ ํ๋ ์คํ ์ด์ง๋ UDF ์์ ์ ๊ฐ ์ฝ์ ์ ์์ด์ผ ํฉ๋๋ค. ๋ํ ZIP ํ์ผ์ด ์์ฒด ํฌํจ๋์ด์ผ ํ๋ฉฐ ์คํํ ์ถ๊ฐ ์ค์ ์คํฌ๋ฆฝํธ์ ์์กดํ๋ฉด ์ ๋ฉ๋๋ค.
์์ค ์ฝ๋๊ฐ ํฌํจ๋ sleepy.py
๋ผ๋ Python ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ๋ง๋ญ๋๋ค.
def snore(n): # return a series of n snores
result = []
for a in range(n):
result.append("Zzz")
return result
SnowSQL(CLI ํด๋ผ์ด์ธํธ) ๋ฅผ ์์ํ๊ณ PUT ๋ช
๋ น์ ์ฌ์ฉํ์ฌ ํ์ผ์ ๋ก์ปฌ ํ์ผ ์์คํ
์์ @~
๋ผ๋ ๊ธฐ๋ณธ ์ฌ์ฉ์ ์คํ
์ด์ง๋ก ๋ณต์ฌํฉ๋๋ค. (PUT
๋ช
๋ น์ Snowflake GUI๋ฅผ ํตํด ์คํํ ์ ์์ต๋๋ค.)
put
file:///Users/Me/sleepy.py
@~/
auto_compress = false
overwrite = true
;
ํ์ผ์ ์ญ์ ํ๊ฑฐ๋ ์ด๋ฆ์ ๋ฐ๊พธ๋ฉด ๋ ์ด์ UDF๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค. ํ์ผ์ ์
๋ฐ์ดํธํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ UDF๋ฅผ ํธ์ถํ ์ ์๋ ๋์ ์
๋ฐ์ดํธํ์ญ์์ค. ์ด์ ํ์ผ์ด ์์ง ์คํ
์ด์ง์ ์๋ ๊ฒฝ์ฐ, PUT
๋ช
๋ น์ OVERWRITE=TRUE
์ ์ด ํฌํจ๋์ด์ผ ํฉ๋๋ค.
UDF๋ฅผ ๋ง๋ญ๋๋ค. ์ด ํธ๋ค๋ฌ๋ ๋ชจ๋๊ณผ ํจ์๋ฅผ ์ง์ ํฉ๋๋ค.
CREATE OR REPLACE FUNCTION dream(i INT)
RETURNS VARIANT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
HANDLER = 'sleepy.snore'
IMPORTS = ('@~/sleepy.py')
UDF๋ฅผ ํธ์ถํฉ๋๋ค.
SELECT dream(3);
+----------+
| DREAM(3) |
|----------|
| [ |
| "Zzz", |
| "Zzz", |
| "Zzz" |
| ] |
+----------+
์ฌ๋ฌ ๊ฐ์ ธ์ค๊ธฐ ํ์ผ ์ง์ ํ๊ธฐยถ
๋ค์์ ์ฌ๋ฌ ๊ฐ์ ธ์ค๊ธฐ ํ์ผ์ ์ง์ ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ์์ ์ ๋๋ค.
CREATE OR REPLACE FUNCTION multiple_import_files(s STRING)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
IMPORTS = ('@python_udf_dep/bar/python_imports_a.zip', '@python_udf_dep/foo/python_imports_b.zip')
HANDLER = 'compute'
AS $$
def compute(s):
return s
$$;
์ฐธ๊ณ
์ง์ ๋ ๊ฐ์ ธ์ค๊ธฐ ํ์ผ ์ด๋ฆ์ ์๋ก ๋ฌ๋ผ์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด imports=('@python_udf_dep/bar/python_imports.zip', '@python_udf_dep/foo/python_imports.zip')
์ ์๋ํ์ง ์์ต๋๋ค.
ํจ์์ ๋ํ ๊ถํ ๋ถ์ฌํ๊ธฐยถ
ํจ์ ์์ ์ ์ด์ธ์ ์ญํ ์ด ํจ์๋ฅผ ํธ์ถํ๋ ค๋ฉด ์์ ์๊ฐ ์ญํ ์ ์ ์ ํ ๊ถํ์ ๋ถ์ฌํด์ผ ํฉ๋๋ค.
Python UDF์ ๋ํ GRANT ๋ฌธ์ JavaScript UDF์ ๊ฐ์ ๋ค๋ฅธ UDF์ ๋ํ GRANT ๋ฌธ๊ณผ ๋ณธ์ง์ ์ผ๋ก ๋์ผํฉ๋๋ค.
์:
GRANT USAGE ON FUNCTION my_python_udf(number, number) TO my_role;