Snowflake Python에서 사용하는 법(Python Connector, Snowpark)


  • 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을 위한 데이터 리터러시 강의를 만들었습니다. 문제 정의, 지표, 실험 설계, 문화 만들기, 로그 설계, 회고 등을 담은 강의입니다

이 글이 도움이 되셨거나 다양한 의견이 있다면 댓글 부탁드립니다 :)

Buy me a coffeeBuy me a coffee





© 2017. by Seongyun Byeon

Powered by zzsza