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분

카일스쿨 유튜브 채널을 만들었습니다. 데이터 분석, 커리어에 대한 내용을 공유드릴 예정입니다.

PM을 위한 데이터 리터러시 강의를 만들었습니다. 문제 정의, 지표, 실험 설계, 문화 만들기, 로그 설계, 회고 등을 담은 강의입니다

이 글이 도움이 되셨거나 의견이 있으시면 댓글 남겨주셔요.

Buy me a coffeeBuy me a coffee





© 2017. by Seongyun Byeon

Powered by zzsza