Snowflake Python에서 사용하는 법(Python Connector, Snowpark)
in Data Engineering on Snowflake
- Snowflake를 Python에서 사용하는 방법에 대해 작성한 글입니다
- Snowsight에서 Python Worksheet를 실행하는 방법이 아닌 Jupyter Notebook에서 사용할 때의 방법을 정리했습니다
Snowflake Python 사용하는 방법
- Snowflake를 사용하는 방법은
- (1) Python Connector를 사용하는 방법
- (2) Snowpark를 사용하는 방법
- 그 외 Snowsight의 Python Worksheet는 사용하기 불편한 부분이 있어 제외했으나, 추후 인터랙티브하게 실행이 가능하다면 Snowsight에서 하는 것이 편해보임
- Jupyter Notebook 환경에서 데이터 분석을 하고 싶은 경우를 위한 글
- 쿼리 실행 엔진을 Snowflake로 둔다고 보면 됨
Python Connector 사용하기
설치하기
- pandas도 사용할 예정이라 pandas 디펜던시 버전을 설치
pip install "snowflake-connector-python[pandas]"==3.0.3
설정 확인 코드
import snowflake.connector
# Gets the version
ctx = snowflake.connector.connect(
user='<your_user_name>',
password='<your_password>',
account='<your_account_name>'
)
cs = ctx.cursor()
try:
cs.execute("SELECT current_version()")
one_row = cs.fetchone()
print(one_row[0])
finally:
cs.close()
ctx.close()
- 여기서 user, password는 생성할 때 사용한 것을 활용하면 됨
- account의 경우 계정 식별자 문서를 보며 확인함
- Snowsight 웹 콘솔에 접근한 후, Admin - Accounts를 클릭
- Account에 CK50244라고 나와있는데, 이 값으로 실행이 되지 않음
- CK50244에 마우스를 올리면 복사할 수 있음. 해당 화면엔 xlwoivr-ck50244가 account임
- 버전이 출력되면 정상적으로 실행된 것!
Account 확인하는 방법
코드를 실행하면 나오는 결과
- connect Method의 파라미터로 warehouse, database, schema를 사용할 수도 있음
쿼리 실행
import snowflake.connector
conn = snowflake.connector.connect(
user='<your_user_name>',
password='<your_password>',
account='<your_account_name>'
)
query = """
SELECT
O_ORDERDATE as date,
COUNT(O_ORDERDATE) as orders
FROM
SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.ORDERS
GROUP BY
O_ORDERDATE
ORDER BY
O_ORDERDATE
LIMIT 10
"""
data = conn.cursor().execute(query)
df = data.fetch_pandas_all()
# conn.close() # 사용을 다 했다면 커넥션 종료
- Connect 객체를 만든 후,
cursor().execute(쿼리)
로 실행 - 그리고
fetch_pandas_all()
을 실행하면 Pandas 데이터프레임을 반환함- 만약 사용을 다 했다면
conn.close()
을 사용해 커넥션을 종료
- 만약 사용을 다 했다면
데이터를 쿼리한 결과
- 특정 Database, Schema를 사용하고 싶다면 다음과 같은 코드를 추가해야 함
conn.cursor().execute("USE DATABASE {DB 이름}")
conn.cursor().execute("USE SCHEMA {스키마 이름}")
Snowflake SQL 문법
- Snowflake SQL 문법은 공식 문서에서 확인할 수 있음
- Query Syntax - SELECT 등을 클릭해 세부 정보를 파악할 수 있음
- 필요할 때마다 snowflake sql {질문} 을 통해 검색하는 것을 추천
키 페어 인증 방법
- 위에서 사용한 예시 코드는 아이디, 비밀번호를 사용하는데 이런 방식을 사용하는 것은 보안상 좋지 않으며, 실무에서도 이렇게 사용하는 경우는 거의 없음
- 많이 활용되는 Key 인증 방법은 키 페어 인증
- 그 외 방법은 보안 문서에서 확인할 수 있음(SSO, MFA, Oauth 등)
개인 키 생성
- 터미널에서 다음과 같은 명령어 입력
- 암호화된 버전을 생성하고 싶으면 아래 명령어에서
-nocrypt
를 제외하면 됨
- 암호화된 버전을 생성하고 싶으면 아래 명령어에서
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
- cat 명령어로 확인
cat rsa_key.p8
개인 키 확인
공개 키 생성
- 개인 키를 사용해 공개 키 생성
- 아래 명령어를 실행하면
rsa_key.pub
파일이 생성됨
- 아래 명령어를 실행하면
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
- cat 명령어로 확인
공개 키 확인
- 키가 유출되면 보안상 좋지 않으므로 키를 안전한 폴더로 이동
공개 키를 Snowflake User에 할당
ALTER USER
명령어를 사용해 Snowflake User에게 공개 키를 할당- Snowsight 콘솔에서 실행
- 단, SECURITYADMIN 역할 이상의 사용자만 실행할 수 있음
- RSA_PUBLIC_KEY는 2개만 등록할 수 있음
ALTER USER {여러분의 username} SET RSA_PUBLIC_KEY='MIIBIjANBgk...';
키 등록 여부 확인
- DESCRIBE USER 명령어를 사용해 사용자 정보를 확인할 수 있음
DESC USER {여러분들의 username}
RSA_PUBLIC_KEY에서 확인할 수 있음
예시 코드
import snowflake.connector
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.hazmat.primitives import serialization
with open("./rsa_key.p8", "rb") as key:
p_key= serialization.load_pem_private_key(
key.read(),
password=None, # 만약 비밀번호가 있다면 '비밀번호'.encode(),
backend=default_backend()
)
pkb = p_key.private_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption())
conn = snowflake.connector.connect(
user='{user_name}',
account='{account}',
private_key=pkb,
)
- 개인 키를 생성할 때 비밀번호를 입력하지 않아서 password=None으로 설정
- 만약 비밀번호가 있다면 비밀번호를 인코딩해야 함
키를 사용해 쿼리를 실행한 예시
Snowpark 사용하기
- Snowpark는 Snowflake에서 개발자를 위한 인터페이스를 제공한다고 나와있으며, 현재 활발히 개발하고 있는 것으로 예상
- Apache Spark의 코드와 유사함
- 23년 5월 30일 기준 Python 3.8에서 설치할 수 있음(3.9에도 사용이 어려움)
- 만약 3.8 버전을 사용하지 않는다면 Pyenv 등을 활용해 버전을 3.8으로 정의
설치하기
- Pandas 디펜던시 버전을 설치
pip install "snowflake-snowpark-python[pandas]"==1.4.0
세션 만들기
- Connection 설정을 주입해 Session을 만들어야 함
- Python Connector에서 사용한 코드를 재사용
from snowflake.snowpark import Session
from snowflake.snowpark.functions import col
import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.hazmat.primitives import serialization
with open("./rsa_key.p8", "rb") as key:
p_key= serialization.load_pem_private_key(
key.read(),
password=None, # 만약 비밀번호가 있다면 '비밀번호'.encode(),
backend=default_backend()
)
pkb = p_key.private_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption())
connection_parameters = {
"user": "<your snowflake user>",
"account": "<your snowflake account>",
"private_key": pkb,
}
- 이제 새로운 Session 생성
new_session = Session.builder.configs(connection_parameters).create()
쿼리 실행
- 쿼리를 실행하는 방법이 다양해서 처음에 헷갈릴 수 있음
- 1) SQL 쿼리 주입 후, Snowpark Dataframe으로 사용
- 2) SQL 쿼리 주입 후, Pandas Dataframe으로 사용
- Spark처럼 쿼리문을 넣고,
collect()
함수를 사용해야 실제로 쿼리가 진행됨
query = """
SELECT
O_ORDERDATE as date,
COUNT(O_ORDERDATE) as orders
FROM
SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.ORDERS
GROUP BY
O_ORDERDATE
ORDER BY
O_ORDERDATE
LIMIT 10
"""
df = new_session.sql(query).collect()
쿼리 실행한 방법
- 또는
collect()
를 사용하지 않고, Snowpark Dataframe 함수를 사용할 수 있음
df3 = new_session.sql(query)
df3.select("DATE").show()
Snowpark Dataframe 함수
- 또는
to_pandas()
를 사용해 바로 Pandas Dataframe으로 변경할 수 있음
df2 = new_session.sql(query).to_pandas()
df2.head()
쿼리 결과를 Pandas Dataframe으로 반환
Snowpark Dataframe API
- Snowpark를 사용하고 싶은 경우 별도의 문법을 파악해야 함
- 공식 문서를 통해 확인할 수 있으나, 사용자 친화적으로 문서가 작성되어 있진 않아 보기 어려움
- Developer Guide가 예시가 더 있어서 보기 수월함
- 이 문서를 익히는 것도 방법
정리
- Snowflake를 Python으로 사용하고 싶은 경우
- Python Connector
- Python Snowpark
- 크게 2가지로 사용할 수 있음
- Snowpark는 Spark스럽게 사용할 수 있으며, 어떤 방법을 사용해도 Snowflake SQL 문법은 잘 익혀야 좋음. SQL 문법으로 Snowflake에 쿼리를 실행한 후, 데이터를 가져오는 방식으로 진행될 것
- Snowpark API 문서를 익히는 것보다 Snowflake SQL을 익히는 것이 조금 더 수월할 수 있음
글 작성하는데 걸린 시간 : 2시간 12분
카일스쿨 유튜브 채널을 만들었습니다. 데이터 사이언스, 성장, 리더십, BigQuery 등을 이야기할 예정이니, 관심 있으시면 구독 부탁드립니다 :)
PM을 위한 데이터 리터러시 강의를 만들었습니다. 문제 정의, 지표, 실험 설계, 문화 만들기, 로그 설계, 회고 등을 담은 강의입니다
이 글이 도움이 되셨거나 다양한 의견이 있다면 댓글 부탁드립니다 :)