Python ์ปค๋„ฅํ„ฐ APIยถ

Python์šฉ Snowflake Connector๋Š” Python Database API v2.0 ์‚ฌ์–‘(PEP-249)์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•ญ๋ชฉ์—์„œ๋Š” ํ‘œ์ค€ API์™€ Snowflake ๊ณ ์œ  ํ™•์žฅ์— ๋Œ€ํ•ด ๋‹ค๋ฃน๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ PEP-249 ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ด ํ•ญ๋ชฉ์˜ ๋‚ด์šฉ:

๋ชจ๋“ˆ: snowflake.connectorยถ

๊ธฐ๋ณธ ๋ชจ๋“ˆ์€ snowflake.connector ์ด๋ฉฐ, ์ด ๋ชจ๋“ˆ์—์„œ๋Š” Connection ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Error ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ƒ์ˆ˜ยถ

apilevelยถ

์ง€์›๋˜๋Š” API ๋ ˆ๋ฒจ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด ์ƒ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ปค๋„ฅํ„ฐ๋Š” API "2.0" ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

threadsafetyยถ

์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ง€์›๋˜๋Š” ์Šค๋ ˆ๋“œ ์•ˆ์ „ ๋ ˆ๋ฒจ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ •์ˆ˜ ์ƒ์ˆ˜์ž…๋‹ˆ๋‹ค. Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ๋Š” ๋ ˆ๋ฒจ 2 ๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ์ด๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชจ๋“ˆ ๋ฐ ์—ฐ๊ฒฐ์„ ๊ณต์œ ํ•จ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

paramstyleยถ

์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์š”๊ตฌ๋˜๋Š” ๋งค๊ฐœ ๋ณ€์ˆ˜ ๋งˆ์ปค ํ˜•์‹์˜ ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด ์ƒ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ปค๋„ฅํ„ฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ "pyformat" ํƒ€์ž…์„ ์ง€์ •ํ•˜๋ฉฐ, ์ด๋Š” Python ํ™•์žฅ ํ˜•์‹ ์ฝ”๋“œ(์˜ˆ: ...WHERE name=%s ๋˜๋Š” ...WHERE name=%(name)s)์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. Connection.connect ๋Š” paramstyle ์„ ์žฌ์ •์˜ํ•˜์—ฌ ๋ฐ”์ธ๋”ฉ ๋ณ€์ˆ˜ ํ˜•์‹์„ "qmark" ๋˜๋Š” "numeric" ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉฐ, ์—ฌ๊ธฐ์„œ ๋ณ€์ˆ˜๋Š” ๊ฐ๊ฐ ? ๋˜๋Š” :N ์ž…๋‹ˆ๋‹ค.

์˜ˆ:

format: .execute("... WHERE my_column = %s", (value,))
pyformat: .execute("... WHERE my_column = %(name)s", {"name": value})
qmark: .execute("... WHERE my_column = ?", (value,))
numeric: .execute("... WHERE my_column = :1", (value,))
Copy

์ฐธ๊ณ 

๋ฐ”์ธ๋”ฉ ๋ณ€์ˆ˜๋Š” paramstyle ์ด "pyformat" ๋˜๋Š” "format" ์ธ ๊ฒฝ์šฐ์—๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ๊ทธ๋ฆฌ๊ณ  "qmark" ๋˜๋Š” "numeric" ์ธ ๊ฒฝ์šฐ์—๋Š” ์„œ๋ฒ„ ์ธก์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„ฅํ„ฐ๋Š” SQL ํ…์ŠคํŠธ๋ฅผ ์ปดํŒŒ์ผํ•œ ํ›„ ๋‹ค์ค‘ ์‹คํ–‰์„ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ํ˜„์žฌ ์„ฑ๋Šฅ ๋˜๋Š” ๊ธฐ๋Šฅ์˜ ์ธก๋ฉด์—์„œ ์ด๋Ÿฌํ•œ ์˜ต์…˜ ์‚ฌ์ด์—๋Š” ์ปค๋‹ค๋ž€ ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , "qmark" ๋ฐ "numeric" ์˜ต์…˜์€ ๋‹ค๋ฅธ ๋“œ๋ผ์ด๋ฒ„(์ฆ‰, JDBC, ODBC, Go Snowflake Driver)์˜ ์ฟผ๋ฆฌ ํ…์ŠคํŠธ์™€ ํ˜ธํ™˜๋˜๋ฉฐ, ์ด๋Š” ? ๋˜๋Š” :N ๋ณ€์ˆ˜ ํ˜•์‹์„ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„์ธก ๋ฐ”์ธ๋”ฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

ํ•จ์ˆ˜ยถ

connect(parameters...)ยถ
๋ชฉ์ :

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ์˜ ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒ์„ฑ์ž๋กœ, Connection ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ž๋™ ์ปค๋ฐ‹ ๋ชจ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค (์ฆ‰, ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜๋ฉด ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ปค๋ฐ‹๋จ). ํŠธ๋žœ์žญ์…˜์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ, BEGIN ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ  COMMIT ๋˜๋Š” ROLLBACK ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•˜๊ฑฐ๋‚˜ ๋กค๋ฐฑํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์œ ํšจํ•œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜:

๋งค๊ฐœ ๋ณ€์ˆ˜

ํ•„์ˆ˜

์„ค๋ช…

account

์˜ˆ

์‚ฌ์šฉ์ž์˜ ๊ณ„์ • ์‹๋ณ„์ž์ž…๋‹ˆ๋‹ค. ๊ณ„์ • ์‹๋ณ„์ž์—๋Š” snowflakecomputing.com ์ ‘๋ฏธ์‚ฌ๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. . . ์ž์„ธํ•œ ์ •๋ณด๋Š” ์˜ˆ๋Š” ์ด ํ•ญ๋ชฉ์˜ ์‚ฌ์šฉ๋ฒ• ๋…ธํŠธ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

user

์˜ˆ

์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

password

์˜ˆ

์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.

application

์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹๋ณ„ํ•˜๋Š” ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

region

๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ ์ด ๋งค๊ฐœ ๋ณ€์ˆ˜ ์„ค๋ช…์€ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ๋งŒ์„ ์œ„ํ•ด์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

host

ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

port

ํฌํŠธ ๋ฒˆํ˜ธ(๊ธฐ๋ณธ๊ฐ’์€ 443)์ž…๋‹ˆ๋‹ค.

database

์‚ฌ์šฉํ•  ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธํ•œ ํ›„์—๋Š” USE DATABASE ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

schema

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉํ•  ๊ธฐ๋ณธ ์Šคํ‚ค๋งˆ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธํ•œ ํ›„์—๋Š” USE SCHEMA ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํ‚ค๋งˆ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

role

์‚ฌ์šฉํ•  ๊ธฐ๋ณธ ์—ญํ• ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธํ•œ ํ›„์—๋Š” USE ROLE ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ญํ• ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

warehouse

์‚ฌ์šฉํ•  ๊ธฐ๋ณธ ์›จ์–ดํ•˜์šฐ์Šค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธํ•œ ํ›„์—๋Š” USE WAREHOUSE ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›จ์–ดํ•˜์šฐ์Šค๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

passcode_in_password

๊ธฐ๋ณธ์ ์œผ๋กœ False ์ž…๋‹ˆ๋‹ค. MFA(๋‹ค๋‹จ๊ณ„ ์ธ์ฆ) ์•”ํ˜ธ๊ฐ€ ๋กœ๊ทธ์ธ ์•”ํ˜ธ์— ํฌํ•จ๋œ ๊ฒฝ์šฐ ์ด ๊ฐ’์„ True ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

passcode

๋กœ๊ทธ์ธ์—์„œ MFA(๋‹ค๋‹จ๊ณ„ ์ธ์ฆ)๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ Duo์—์„œ ์ œ๊ณต๋˜๋Š” ์•”ํ˜ธ์ž…๋‹ˆ๋‹ค.

private_key

์ธ์ฆ์—์„œ ์‚ฌ์šฉํ•  ๊ฐœ์ธ ํ‚ค์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ‚ค ํŽ˜์–ด ์ธ์ฆ ๋ฐ ํ‚ค ํŽ˜์–ด ์ˆœํ™˜ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

private_key_file

์ง€์ •๋œ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ๊ฐœ์ธ ํ‚ค ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํ‚ค ํŽ˜์–ด ์ธ์ฆ ๋ฐ ํ‚ค ํŽ˜์–ด ์ˆœํ™˜ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

private_key_file_pwd

์ง€์ •๋œ ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ ํ‚ค ํŒŒ์ผ์„ ํ•ด๋…ํ•˜๊ธฐ ์œ„ํ•œ ์•”ํ˜ธ ๊ตฌ๋ฌธ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํ‚ค ํŽ˜์–ด ์ธ์ฆ ๋ฐ ํ‚ค ํŽ˜์–ด ์ˆœํ™˜ ์‚ฌ์šฉํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

autocommit

๊ธฐ๋ณธ์ ์œผ๋กœ None ์ด๋ฉฐ, Snowflake ๋งค๊ฐœ ๋ณ€์ˆ˜ AUTOCOMMIT ์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์„ธ์…˜์—์„œ ์ž๋™ ์ปค๋ฐ‹ ๋ชจ๋“œ๋ฅผ ํ™œ์„ฑํ™” ๋˜๋Š” ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด ๊ฐ๊ฐ True ๋˜๋Š” False ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

client_prefetch_threads

๊ฒฐ๊ณผ ์„ธํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์Šค๋ ˆ๋“œ ์ˆ˜(๊ธฐ๋ณธ์ ์œผ๋กœ 4)์ž…๋‹ˆ๋‹ค. ๊ฐ’์„ ๋Š˜๋ฆฌ๋ฉด ํŽ˜์น˜ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋” ๋งŽ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

client_session_keep_alive

์„ธ์…˜์„ ๋ฌดํ•œ๋Œ€๋กœ ํ™œ์„ฑ์œผ๋กœ ์œ ์ง€ํ•˜๋ ค๋ฉด(์‚ฌ์šฉ์ž์˜ ํ™œ๋™์ด ์—†๋Š” ๊ฒฝ์šฐ์—๋„) ์ด ๊ฐ’์„ True ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์„ True ๋กœ ์„ค์ •ํ•˜๋ฉด close ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ์Šค๋ ˆ๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ ์‚ฌ์šฉ ์ค‘์ธ ์ปค๋„ฅํ„ฐ์˜ ๋ฒ„์ „์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

  • ๋ฒ„์ „ 2.4.6 ์ด์ƒ: ๊ธฐ๋ณธ์ ์œผ๋กœ None ์ž…๋‹ˆ๋‹ค. . ๊ฐ’์ด None ์ธ ๊ฒฝ์šฐ CLIENT_SESSION_KEEP_ALIVE ์„ธ์…˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. . . ์„ธ์…˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•˜๋ ค๋ฉด ์ด ์ธ์ž์— True ๋˜๋Š” False ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒ„์ „ 2.4.5 ์ด์ „: ๊ธฐ๋ณธ์ ์œผ๋กœ False ์ž…๋‹ˆ๋‹ค. . ์ด ๊ฐ’์ด False (๊ฐ’์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ์ธ์ž๋ฅผ ์ƒ๋žตํ•˜์—ฌ)์ธ ๊ฒฝ์šฐ CLIENT_SESSION_KEEP_ALIVE ์„ธ์…˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. . .

connect ๋ฉ”์„œ๋“œ์— client_session_keep_alive=False ๋ฅผ ์ „๋‹ฌํ•ด๋„ CLIENT_SESSION_KEEP_ALIVE ์„ธ์…˜ ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ๊ฐ’ TRUE ๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

login_timeout

๋กœ๊ทธ์ธ์˜ ์‹œ๊ฐ„ ์ œํ•œ(์ดˆ)์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ 60์ดˆ์ž…๋‹ˆ๋‹ค. HTTP ์‘๋‹ต์ด โ€œ์„ฑ๊ณตโ€์ธ ๊ฒฝ์šฐ ์‹œ๊ฐ„ ์ œํ•œ ๊ธธ์ด ์ดํ›„์—๋Š” ๋กœ๊ทธ์ธ ์š”์ฒญ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

network_timeout

๊ธฐํƒ€ ๋ชจ๋“  ์ž‘์—…์˜ ์‹œ๊ฐ„ ์ œํ•œ(์ดˆ)์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์—†์Œ/๋ฌดํ•œ๋Œ€์ž…๋‹ˆ๋‹ค. HTTP ์‘๋‹ต์ด โ€œ์„ฑ๊ณตโ€์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์‹œ๊ฐ„ ์ œํ•œ ๊ธธ์ด ์ดํ›„์—๋Š” ์ผ๋ฐ˜ ์š”์ฒญ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ocsp_response_cache_filename

OCSP ์‘๋‹ต ์บ์‹œ ํŒŒ์ผ์— ๋Œ€ํ•œ URI์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ OCSP ์‘๋‹ต ์บ์‹œ ํŒŒ์ผ์€ ๋‹ค์Œ ์บ์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

  • Linux: ~/.cache/snowflake/ocsp_response_cache

  • macOS: ~/Library/Caches/Snowflake/ocsp_response_cache

  • Windows: %USERPROFILE%AppDataLocalSnowflakeCachesocsp_response_cache

๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ํŒŒ์ผ์„ ์ฐพ์œผ๋ ค๋ฉด, URI ์— ๊ฒฝ๋กœ์™€ ํŒŒ์ผ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: file:///tmp/my_ocsp_response_cache.txt).

authenticator

Snowflake์šฉ ์ธ์ฆ์ž:

  • ๋‚ด๋ถ€ Snowflake ์ธ์ฆ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด snowflake (๊ธฐ๋ณธ๊ฐ’).

  • ์›น ๋ธŒ๋ผ์šฐ์ € ๋ฐ Okta, AD FS ๋˜๋Š” ๊ณ„์ •์— ์ •์˜๋œ ๊ธฐํƒ€ ๋ชจ๋“  SAML 2.0 ๊ทœ๊ฒฉ ID ๊ณต๊ธ‰์ž(IdP)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆํ•˜๋ ค๋ฉด externalbrowser.

  • ๊ธฐ๋ณธ Okta๋ฅผ ํ†ตํ•ด ์ธ์ฆํ•˜๋ ค๋ฉด https://<okta_๊ณ„์ •_์ด๋ฆ„>.okta.com (์ฆ‰, Okta ๊ณ„์ •์˜ URL ์—”๋“œํฌ์ธํŠธ).

  • OAuth๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆํ•˜๋ ค๋ฉด oauth. token ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜๊ณ  ๊ฐ’์„ OAuth ์•ก์„ธ์Šค ํ† ํฐ์œผ๋กœ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • MFA ํ† ํฐ ์บ์‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆํ•˜๋ ค๋ฉด username_password_mfa. ์ž์„ธํ•œ ๋‚ด์šฉ์€ MFA ํ† ํฐ ์บ์‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ ๋„์ค‘ ํ”„๋กฌํ”„ํŠธ ์ˆ˜ ์ตœ์†Œํ™”ํ•˜๊ธฐ โ€” ์„ ํƒ ์‚ฌํ•ญ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

  • OAuth 2.0 Authorization Code ํ๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ OAUTH_AUTHORIZATION_CODE.

  • OAuth 2.0 Client Credentials ํ๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ OAUTH_CLIENT_CREDENTIALS

์ด ๊ฐ’์ด snowflake ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž ๋ฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” IdP์˜ ๋กœ๊ทธ์ธ ์ž๊ฒฉ ์ฆ๋ช…์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

validate_default_parameters

๊ธฐ๋ณธ์ ์œผ๋กœ False ์ž…๋‹ˆ๋‹ค. True ์ธ ๊ฒฝ์šฐ:

  • ์ง€์ •๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ์Šคํ‚ค๋งˆ ๋˜๋Š” ์›จ์–ดํ•˜์šฐ์Šค๊ฐ€ ์—†์œผ๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ์œ ํšจํ•˜์ง€ ์•Š์€ ์ธ์ž ์ด๋ฆ„ ๋˜๋Š” ์ž˜๋ชป๋œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ์ธ์ž ๊ฐ’์ด ์ „๋‹ฌ๋˜๋ฉด stderr์— ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

paramstyle

ํด๋ผ์ด์–ธํŠธ์ธก ๋ฐ”์ธ๋”ฉ์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ pyformat ์ž…๋‹ˆ๋‹ค. qmark ๋˜๋Š” numeric ๋ฅผ ์ง€์ •ํ•˜์—ฌ ์„œ๋ฒ„์ธก ๋ฐ”์ธ๋”ฉ์˜ ๋ฐ”์ธ๋”ฉ ๋ณ€์ˆ˜ ํ˜•์‹์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

timezone

๊ธฐ๋ณธ์ ์œผ๋กœ None ์ด๋ฉฐ, Snowflake ๋งค๊ฐœ ๋ณ€์ˆ˜ TIMEZONE ์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์œ ํšจํ•œ ํƒ€์ž„์กด(์˜ˆ: America/Los_Angeles)์„ ์„ค์ •ํ•˜์—ฌ ์„ธ์…˜ ํƒ€์ž„์กด์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

arrow_number_to_decimal

๊ธฐ๋ณธ์ ์œผ๋กœ False ์ด๋ฉฐ, ์ฆ‰ NUMBER ์—ด ๊ฐ’์€ ๋ฐฐ์ •๋ฐ€๋„ ๋ถ€๋™ ์†Œ์ˆ˜์  ์ˆซ์ž(float64)๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. . . fetch_pandas_all() ๋ฐ fetch_pandas_batches() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ DECIMAL ์—ด ๊ฐ’์„ 10์ง„์ˆ˜(decimal.Decimal)๋กœ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด ์ด ๊ฐ’์„ True ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. . . ์ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ์˜ 2.4.3 ๋ฒ„์ „์—์„œ ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

socket_timeout

์†Œ์ผ“ ์ˆ˜์ค€ ์ฝ๊ธฐ ๋ฐ ์—ฐ๊ฒฐ ์š”์ฒญ์— ๋Œ€ํ•œ ์‹œ๊ฐ„ ์ œํ•œ(์ดˆ)์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฐ๊ฒฐ ์‹œ๊ฐ„ ์ œํ•œ ๊ด€๋ฆฌํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

backoff_policy

์žฌ์‹œ๋„ ๊ฐ„ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ •์˜ํ•˜๋Š” ์ƒ์„ฑ๊ธฐ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์žฌ์‹œ๋„์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ๋ฐฑ์˜คํ”„ ์ •์ฑ… ๊ด€๋ฆฌํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

enable_connection_diag

์—ฐ๊ฒฐ ์ง„๋‹จ ๋ณด๊ณ ์„œ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์—ฌ๋ถ€. ๊ธฐ๋ณธ๊ฐ’์€ False ์ž…๋‹ˆ๋‹ค.

connection_diag_log_path

์ง„๋‹จ ๋ณด๊ณ ์„œ ์œ„์น˜์— ๋Œ€ํ•œ ์ ˆ๋Œ€ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. enable_connection_diag ๊ฐ€ True ์ธ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ ์šด์˜ ์ฒด์ œ์˜ ๊ธฐ๋ณธ ์ž„์‹œ ๋””๋ ‰ํ„ฐ๋ฆฌ(์˜ˆ: Linux ๋˜๋Š” Mac์˜ ๊ฒฝ์šฐ /tmp)์ž…๋‹ˆ๋‹ค.

connection_diag_allowlist_path

SYSTEM$ALLOWLIST() ๋˜๋Š” SYSTEM$ALLOWLIST_PRIVATELINK() ์˜ ์ถœ๋ ฅ์ด ํฌํ•จ๋œ JSON ํŒŒ์ผ์˜ ์ ˆ๋Œ€ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์— ์ •์˜๋œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์‹œ์Šคํ…œ ํ—ˆ์šฉ ๋ชฉ๋ก ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•  ๊ถŒํ•œ์ด ์—†๊ฑฐ๋‚˜ ๊ณ„์ • URL์— ์—ฐ๊ฒฐ์ด ์‹คํŒจํ•œ ๊ฒฝ์šฐ์—๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

iobound_tpe_limit

preprocess_tpe ๋ฐ postprocess TPE(threadpool executor)์˜ ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ’์€ ํŒŒ์ผ ์ˆ˜์™€ CPU ์ฝ”์–ด ์ˆ˜ ์ค‘ ์ž‘์€ ์ชฝ์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

unsafe_file_write

GET ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํ…Œ์ด์ง€์—์„œ ๋‹ค์šด๋กœ๋“œํ•œ ํŒŒ์ผ์— ํ• ๋‹นํ•  ํŒŒ์ผ ๊ถŒํ•œ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. False (๊ธฐ๋ณธ๊ฐ’)๋กœ ์ง€์ •ํ•˜๋ฉด ํŒŒ์ผ ๊ถŒํ•œ์„ 600 ์œผ๋กœ ์„ค์ •ํ•˜์—ฌ ์†Œ์œ ์ž๋งŒ ํŒŒ์ผ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. True ๋ฅผ ์ง€์ •ํ•˜๋ฉด ๊ถŒํ•œ์„ 644 ๋กœ ์„ค์ •ํ•˜์—ฌ ์†Œ์œ ์ž์—๊ฒŒ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๊ณ , ๊ทธ ์™ธ ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ์ฝ๊ธฐ ์ „์šฉ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ฐ์ดํ„ฐ ๋‹ค์šด๋กœ๋“œํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

oauth_client_id

client id ์˜ ๊ฐ’์€ Snowflake ํ†ตํ•ฉ์„ ์œ„ํ•ด ID ๊ณต๊ธ‰์ž๊ฐ€ ์ œ๊ณตํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค(Snowflake ๋ณด์•ˆ ํ†ตํ•ฉ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ).

oauth_client_secret

client secret ์˜ ๊ฐ’์€ Snowflake ํ†ตํ•ฉ์„ ์œ„ํ•ด ID ๊ณต๊ธ‰์ž๊ฐ€ ์ œ๊ณตํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค(Snowflake ๋ณด์•ˆ ํ†ตํ•ฉ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ).

oauth_authorization_url

๋“œ๋ผ์ด๋ฒ„์— ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ID ๊ณต๊ธ‰์ž ์—”๋“œํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค. Snowflake๋ฅผ ID ๊ณต๊ธ‰์ž๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๊ฐ’์€ server ๋˜๋Š” account ๋งค๊ฐœ ๋ณ€์ˆ˜์—์„œ ํŒŒ์ƒ๋ฉ๋‹ˆ๋‹ค.

oauth_token_request_url

๋“œ๋ผ์ด๋ฒ„์— ์•ก์„ธ์Šค ํ† ํฐ์„ ์ œ๊ณตํ•˜๋Š” ID ๊ณต๊ธ‰์ž ์—”๋“œํฌ์ธํŠธ์ž…๋‹ˆ๋‹ค. Snowflake๋ฅผ ID ๊ณต๊ธ‰์ž๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๊ฐ’์€ server ๋˜๋Š” account ๋งค๊ฐœ ๋ณ€์ˆ˜์—์„œ ํŒŒ์ƒ๋ฉ๋‹ˆ๋‹ค.

oauth_scope

ID ๊ณต๊ธ‰์ž ์Šน์ธ ์š”์ฒญ์—์„œ ์š”์ฒญ๋œ ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์—ญํ• ์—์„œ ํŒŒ์ƒ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋ฒ”์œ„๊ฐ€ ์š”๊ตฌ๋˜๋Š” ๊ฒฝ์šฐ ๊ฐ’์€ ๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„๋œ ์—ฌ๋Ÿฌ ๋ฒ”์œ„์˜ ๋ชฉ๋ก์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

oauth_redirect_uri

์ธ์ฆ ์ฝ”๋“œ ๋ฆฌ๋””๋ ‰์…˜์— ์‚ฌ์šฉํ•˜๋Š” URI (Snowflake ๋ณด์•ˆ ํ†ตํ•ฉ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ)์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’: http://127.0.0.1:{randomAvailablePort}/.

oauth_disable_pkce:

์•…์˜์ ์ธ ๊ณต๊ฒฉ์ž๊ฐ€ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ๊ฐ€๋กœ์ฑ„๋”๋ผ๋„ ์œ ํšจํ•œ ์•ก์„ธ์Šค ํ† ํฐ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋„๋ก ํ•˜๋Š” ๋ณด์•ˆ ๊ฐœ์„  ์‚ฌํ•ญ์ธ PKCE (Proof Key for Code Exchange)๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

oauth_enable_refresh_token:

์‹ค์ œ ์•ก์„ธ์Šค ํ† ํฐ์ด ์˜ค๋ž˜๋˜์—ˆ์„ ๋•Œ ์ž๋™ ์žฌ์ธ์ฆ์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค(์ธ์ฆ ์„œ๋ฒ„์—์„œ ์ง€์›๋˜๊ณ  client_store_temporary_credential ์ด True ๋กœ ์„ค์ •๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ).

oauth_enable_single_use_refresh_tokens:

์ผํšŒ์šฉ ์ƒˆ๋กœ ๊ณ ์นจ ํ† ํฐ ์‹œ๋งจํ‹ฑ์— ์˜ตํŠธ์ธํ• ์ง€ ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค.

์†์„ฑยถ

Error, Warning, ...

Python ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค API ํ‘œ์ค€์— ์˜ํ•ด ์ •์˜๋˜๋Š” ๋ชจ๋“  ์˜ˆ์™ธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ๋Š” msg, errno, sqlstate, sfqid ๋ฐ raw_msg ์†์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

account ๋งค๊ฐœ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์‚ฌ์šฉ๋ฒ• ๋…ธํŠธ(connect ๋ฉ”์„œ๋“œ์šฉ)ยถ

ํ•„์ˆ˜ account ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ, ๊ณ„์ • ์‹๋ณ„์ž ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

๊ณ„์ • ์‹๋ณ„์ž์—๋Š” snowflakecomputing.com ๋„๋ฉ”์ธ ์ด๋ฆ„์ด ํฌํ•จ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค. ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•  ๋•Œ Snowflake๊ฐ€ ์ด ๊ฐ’์„ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์—์„œ๋Š” ์กฐ์ง myorganization ์˜ ๊ณ„์ • myaccount ์— ๋Œ€ํ•œ ์‹๋ณ„์ž๋กœ ๊ณ„์ • ์ด๋ฆ„ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ctx = snowflake.connector.connect(
    user='<user_name>',
    password='<password>',
    account='myorganization-myaccount',
    ... )
Copy

๋‹ค์Œ ์˜ˆ์—์„œ๋Š” ๊ณ„์ • ๋กœ์ผ€์ดํ„ฐ xy12345 ๋ฅผ ๊ณ„์ • ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ctx = snowflake.connector.connect(
    user='<user_name>',
    password='<password>',
    account='xy12345',
    ... )
Copy

์ด ์˜ˆ์—์„œ๋Š” AWS US ์„œ๋ถ€(์˜ค๋ ˆ๊ณค) ๋ฆฌ์ „์˜ ๊ณ„์ •์„ ์‚ฌ์šฉํ•จ์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค. ๊ณ„์ •์ด ๋‹ค๋ฅธ ๋ฆฌ์ „์— ์žˆ๊ฑฐ๋‚˜ ๊ณ„์ •์ด ๋‹ค๋ฅธ ํด๋ผ์šฐ๋“œ ๊ณต๊ธ‰์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊ณ„์ • ๋กœ์ผ€์ดํ„ฐ ๋‹ค์Œ์— ์ถ”๊ฐ€ ์„ธ๊ทธ๋จผํŠธ๋ฅผ ์ง€์ • ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋ธŒ์ ํŠธ: Connectionยถ

Connection ์˜ค๋ธŒ์ ํŠธ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์„ ํ™œ์„ฑ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์—ฐ๊ฒฐ ๋ฐ ์„ธ์…˜ ์ •๋ณด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜๊ฑฐ๋‚˜ ์„ธ์…˜์ด ๋งŒ๋ฃŒ๋˜๋ฉด ์ดํ›„์˜ ๋ชจ๋“  ์ž‘์—…์ด ์‹คํŒจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œยถ

autocommit(True|False)ยถ
๋ชฉ์ :

์ž๋™ ์ปค๋ฐ‹ ๋ชจ๋“œ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ฑฐ๋‚˜ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž๋™ ์ปค๋ฐ‹์€ ํ™œ์„ฑํ™”(True)๋ฉ๋‹ˆ๋‹ค.

close()ยถ
๋ชฉ์ :

์—ฐ๊ฒฐ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜์—ˆ์„ ๋•Œ์—๋„ ์—ฌ์ „ํžˆ ํŠธ๋žœ์žญ์…˜์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฉด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋กค๋ฐฑ๋ฉ๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ข…๋ฃŒํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ํ™œ์„ฑ ์„ธ์…˜์ด ์ œ๊ฑฐ๋˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์„œ๋ฒ„์—์„œ ์‚ญ์ œ๋  ๋•Œ๊นŒ์ง€ ํ™œ์„ฑ ์„ธ์…˜์ด ์œ ์ง€๋˜์–ด, ๋™์‹œ ์ฟผ๋ฆฌ์˜ ์ˆ˜๊ฐ€ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ:

# context manager ensures the connection is closed
with snowflake.connector.connect(...) as con:
    con.cursor().execute(...)

# try & finally to ensure the connection is closed.
con = snowflake.connector.connect(...)
try:
    con.cursor().execute(...)
finally:
    con.close()
Copy
commit()ยถ
๋ชฉ์ :

์ž๋™ ์ปค๋ฐ‹์ด ๋น„ํ™œ์„ฑํ™”๋˜๋ฉด ํ˜„์žฌ ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋ฉ๋‹ˆ๋‹ค. ์ž๋™ ์ปค๋ฐ‹์ด ํ™œ์„ฑํ™”๋˜๋ฉด ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

rollback()ยถ
๋ชฉ์ :

์ž๋™ ์ปค๋ฐ‹์ด ๋น„ํ™œ์„ฑํ™”๋˜๋ฉด ํ˜„์žฌ ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ๋ฉ๋‹ˆ๋‹ค. ์ž๋™ ์ปค๋ฐ‹์ด ํ™œ์„ฑํ™”๋˜๋ฉด ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

cursor()ยถ
๋ชฉ์ :

Cursor ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒ์„ฑ์ž์ž…๋‹ˆ๋‹ค. fetch*() ํ˜ธ์ถœ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๋‹จ์ผ ์‹œํ€€์Šค ๋˜๋Š” ์‹œํ€€์Šค์˜ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

cursor(snowflake.connector.DictCursor)
๋ชฉ์ :

DictCursor ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒ์„ฑ์ž์ž…๋‹ˆ๋‹ค. fetch*() ํ˜ธ์ถœ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๋‹จ์ผ dict ๋˜๋Š” dict ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๊ฒฐ๊ณผ์—์„œ ์—ด ์ด๋ฆ„์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

execute_string(sql_text, remove_comments=False, return_cursors=True)ยถ
๋ชฉ์ :

๋ฌธ์ž์—ด๋กœ ์ „๋‹ฌ๋˜๋Š” 1๊ฐœ ์ด์ƒ์˜ SQL ๋ฌธ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. remove_comments ๊ฐ€ True ๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ ์ฟผ๋ฆฌ์—์„œ ์„ค๋ช…์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. return_cursors ๊ฐ€ True ๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ ์ด ๋ฉ”์„œ๋“œ๋Š” ์‹คํ–‰ ์ˆœ์„œ๋กœ Cursor ์˜ค๋ธŒ์ ํŠธ์˜ ์‹œํ€€์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

์ด ์˜ˆ์—์„œ๋Š” ๋‹จ์ผ ๋ฌธ์ž์—ด์—์„œ์˜ ๋‹ค์ค‘ ๋ช…๋ น ์‹คํ–‰ ๋ฐ ๋ฐ˜ํ™˜๋˜๋Š” ์ปค์„œ์˜ ์‹œํ€€์Šค ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

cursor_list = connection1.execute_string(
    "SELECT * FROM testtable WHERE col1 LIKE 'T%';"
    "SELECT * FROM testtable WHERE col2 LIKE 'A%';"
    )

for cursor in cursor_list:
   for row in cursor:
      print(row[0], row[1])
Copy

์ฐธ๊ณ 

๋‹จ์ผ ๋ฌธ์ž์—ด์—์„œ ์—ฌ๋Ÿฌ SQL ๋ฌธ์„ ํ—ˆ์šฉํ•˜๋Š” execute_string() ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋Š” SQL ์‚ฝ์ž… ๊ณต๊ฒฉ์— ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•œ ๊ฒฝ์šฐ๋ฅผ ์ œ์™ธํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•œ ๋ฐ์ดํ„ฐ์™€ SQL์„ ๊ฒฐํ•ฉํ•˜์—ฌ SQL ๋ฌธ์„ ๋™์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด, ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ ๋˜๋Š” Python์˜ format() ๋“ฑ์˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์•„๋ž˜ ์˜ˆ๋Š” ๋ฌธ์ œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

# "Binding" data via the format() function (UNSAFE EXAMPLE)
value1_from_user = "'ok3'); DELETE FROM testtable WHERE col1 = 'ok1'; select pi("
sql_cmd = "insert into testtable(col1) values('ok1'); "                  \
          "insert into testtable(col1) values('ok2'); "                  \
          "insert into testtable(col1) values({col1});".format(col1=value1_from_user)
# Show what SQL Injection can do to a composed statement.
print(sql_cmd)

connection1.execute_string(sql_cmd)
Copy

๋™์ ์œผ๋กœ ๊ตฌ์„ฑ๋œ ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค(๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ์ค„ ๋ฐ”๊ฟˆ์ด ์ถ”๊ฐ€๋จ).

insert into testtable(col1) values('ok1');
insert into testtable(col1) values('ok2');
insert into testtable(col1) values('ok3');
DELETE FROM testtable WHERE col1 = 'ok1';
select pi();
Copy

์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ž์—ด๊ณผ SQL ๋ฌธ์„ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ž์—ด์„ ๊ตฌ์„ฑํ•˜๋Š” ๋Œ€์‹  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฌธ์— ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. execute_string() ๋ฉ”์„œ๋“œ์—์„œ๋Š” ๋ฐ”์ธ๋”ฉ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ Cursor.execute() ๋˜๋Š” Cursor.executemany() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค.

execute_stream(sql_stream, remove_comments=False)ยถ
๋ชฉ์ :

์ŠคํŠธ๋ฆผ ์˜ค๋ธŒ์ ํŠธ๋กœ ์ „๋‹ฌ๋œ 1๊ฐœ ์ด์ƒ์˜ SQL ๋ฌธ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. remove_comments ๊ฐ€ True ๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ ์ฟผ๋ฆฌ์—์„œ ์„ค๋ช…์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์ด ์ƒ์„ฑ๊ธฐ์—์„œ๋Š” SQL ๋ฌธ์ด ์‹คํ–‰๋  ๋•Œ ๊ฐ Cursor ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

sql_stream ์ด ์ฃผ์„ ์ค„๋กœ ๋๋‚˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ remove_comments ๋ฅผ True ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

sql_script = """
-- This is first comment line;
select 1;
select 2;
-- This is comment in middle;
-- With some extra comment lines;
select 3;
-- This is the end with last line comment;
"""
sql_stream = StringIO(sql_script)
with con.cursor() as cur:
        for result_cursor in con.execute_stream(sql_stream,remove_comments=True):
            for result in result_cursor:
                print(f"Result: {result}")
Copy
get_query_status(query_id)ยถ
๋ชฉ์ :

์ฟผ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

query_id

์ฟผ๋ฆฌ์˜ ID์ž…๋‹ˆ๋‹ค. Snowflake ์ฟผ๋ฆฌ ID ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ฐ˜ํ™˜:

์ฟผ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” QueryStatus ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

์ฟผ๋ฆฌ ์ƒํƒœ ํ™•์ธํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

get_query_status_throw_if_error(query_id)ยถ
๋ชฉ์ :

์ฟผ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ด ๋ฉ”์„œ๋“œ์—์„œ๋Š” ProgrammingError ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(execute() ๋ฉ”์„œ๋“œ์—์„œ์™€ ๊ฐ™์ด).

๋งค๊ฐœ ๋ณ€์ˆ˜:

query_id

์ฟผ๋ฆฌ์˜ ID์ž…๋‹ˆ๋‹ค. Snowflake ์ฟผ๋ฆฌ ID ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ฐ˜ํ™˜:

์ฟผ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” QueryStatus ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

์ฟผ๋ฆฌ ์ƒํƒœ ํ™•์ธํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

is_valid()ยถ
๋ชฉ์ :

์—ฐ๊ฒฐ์ด ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์„ ๋งŒํผ ์•ˆ์ •์ ์ด๋ฉด True ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

is_still_running(query_status)ยถ
๋ชฉ์ :

์ฟผ๋ฆฌ ์ƒํƒœ๊ฐ€ ์ฟผ๋ฆฌ๊ฐ€ ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์Œ ๋˜๋Š” ์•„์ง ์ง„ํ–‰ ์ค‘์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉด True ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

query_status

์ฟผ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” QueryStatus ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์ด ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด, ์ฟผ๋ฆฌ ์ƒํƒœ ํ™•์ธํ•˜๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์˜ˆ:

์ฟผ๋ฆฌ ์ƒํƒœ ํ™•์ธํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

is_an_error(query_status)ยถ
๋ชฉ์ :

์ฟผ๋ฆฌ ์ƒํƒœ๊ฐ€ ์ฟผ๋ฆฌ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•จ์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉด True ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

query_status

์ฟผ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” QueryStatus ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์ด ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด, ์ฟผ๋ฆฌ ์ƒํƒœ ํ™•์ธํ•˜๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์˜ˆ:

์ฟผ๋ฆฌ ์ƒํƒœ ํ™•์ธํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์†์„ฑยถ

expiredยถ

์—ฐ๊ฒฐ์˜ ๋งˆ์Šคํ„ฐ ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.

messagesยถ

์ด ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ์ˆ˜์‹ ๋œ ๋ชจ๋“  ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•œ ์‹œํ€€์Šค(์˜ˆ์™ธ ํด๋ž˜์Šค, ์˜ˆ์™ธ ๊ฐ’)๋ฅผ ํฌํ•จํ•˜๋Š” ๋ชฉ๋ก ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค.

๋ชฉ๋ก์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ž๋™์œผ๋กœ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

errorhandlerยถ

์˜ค๋ฅ˜ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋  ๋•Œ ํ˜ธ์ถœํ•  ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ฝ๊ธฐ/์“ฐ๊ธฐ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

์ด ์ฒ˜๋ฆฌ๊ธฐ๋Š” ๋‹ค์Œ ์ธ์ž๋ฅผ ํ—ˆ์šฉํ•˜๊ณ  Python์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

errorhandler(connection, cursor, errorclass, errorvalue)

Error, Warning, ...

Python ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค API ํ‘œ์ค€์— ์˜ํ•ด ์ •์˜๋˜๋Š” ๋ชจ๋“  ์˜ˆ์™ธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

์˜ค๋ธŒ์ ํŠธ: Cursorยถ

Cursor ์˜ค๋ธŒ์ ํŠธ๋Š” ์‹คํ–‰ ๋ฐ ํŽ˜์น˜ ์ž‘์—…์„ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค์„œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๊ฐ ์ปค์„œ์—๋Š” ์ž์ฒด ์†์„ฑ์ธ description ๋ฐ rowcount ๊ฐ€ ์žˆ์–ด, ์ปค์„œ๋ฅผ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œยถ

close()
๋ชฉ์ :

์ปค์„œ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค.

describe(command [, parameters][, timeout][, file_stream])ยถ
๋ชฉ์ :

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ๊ฒฐ๊ณผ ์„ธํŠธ์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฏธ ๋ฉ”์„œ๋“œ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•œ ํ›„ description ์†์„ฑ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋™์ผํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฉ”์„œ๋“œ๋Š” Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ์˜ 2.4.6 ๋ฒ„์ „์—์„œ ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

execute() ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ฐ˜ํ™˜:

๊ฒฐ๊ณผ ์„ธํŠธ์˜ ์—ด์„ ์„ค๋ช…ํ•˜๋Š” ResultMetadata ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

์—ด ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

execute(command [, parameters][, timeout][, file_stream])ยถ
๋ชฉ์ :

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ช…๋ น์„ ์ค€๋น„ํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

command

์‹คํ–‰ํ•  SQL ๋ฌธ์ด ํฌํ•จ๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

parameters

(์„ ํƒ ์‚ฌํ•ญ) SQL ๋ฌธ์—์„œ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ ์„ ์œ„ํ•ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ, ์ด ๊ฐ’์„ ํ•ด๋‹น ๋งค๊ฐœ ๋ณ€์ˆ˜์— ๋ฐ”์ธ๋”ฉํ•ด์•ผ ํ•˜๋Š” ๋ณ€์ˆ˜์˜ ๋ชฉ๋ก ๋˜๋Š” ๋”•์…”๋„ˆ๋ฆฌ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ณ€์ˆ˜์— ๋Œ€ํ•œ Python ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ํ•ด๋‹น ์—ด์˜ SQL ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ qmark ๋ฐ numeric ๋ฐ”์ธ๋”ฉ์šฉ ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋งคํ•‘ ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

timeout

(์„ ํƒ ์‚ฌํ•ญ) ์ฟผ๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ด์•ผ ํ•˜๋Š” ์‹œ๊ฐ„(์ดˆ)์ž…๋‹ˆ๋‹ค. ์ด ์‹œ๊ฐ„์— ๊ฒฝ๊ณผํ•œ ํ›„์— ์ฟผ๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฉด ์ฟผ๋ฆฌ๊ฐ€ ์ค‘๋‹จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

file_stream

(์„ ํƒ ์‚ฌํ•ญ) PUT ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ ์ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ ์‹œ์Šคํ…œ์˜ ํŒŒ์ผ์ด ์•„๋‹Œ ์ธ๋ฉ”๋ชจ๋ฆฌ ํŒŒ์ผ๊ณผ ์œ ์‚ฌํ•œ ์˜ค๋ธŒ์ ํŠธ(์˜ˆ: Python open() ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜๋œ I/O ์˜ค๋ธŒ์ ํŠธ)๋ฅผ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ํ•ด๋‹น I/O ์˜ค๋ธŒ์ ํŠธ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

PUT ๋ช…๋ น์—์„œ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์˜ URI๋ฅผ ์ง€์ •ํ•  ๋•Œ:

  • ์‚ฌ์šฉ์ž๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. URI์— ์ง€์ •ํ•˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฒฝ๋กœ๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

  • ์Šคํ…Œ์ด์ง€์—์„œ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ํŒŒ์ผ์˜ ์ด๋ฆ„์„ ํŒŒ์ผ ์ด๋ฆ„์— ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํŒŒ์ผ ์ŠคํŠธ๋ฆผ์—์„œ ๋‹ค์Œ ์ด๋ฆ„์˜ ํŒŒ์ผ๋กœ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๋ ค๋ฉด:

@mystage/myfile.csv
Copy

๋‹ค์Œ ํ˜ธ์ถœ ์‚ฌ์šฉ:

cursor.execute(
    "PUT file://this_directory_path/is_ignored/myfile.csv @mystage",
    file_stream=<io_object>)
Copy
๋ฐ˜ํ™˜:

Cursor ์˜ค๋ธŒ์ ํŠธ์˜ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

executemany(command, seq_of_parameters)ยถ
๋ชฉ์ :

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ช…๋ น์„ ์ค€๋น„ํ•˜๊ณ  seq_of_parameters ์˜ ๋ชจ๋“  ๋งค๊ฐœ ๋ณ€์ˆ˜ ์‹œํ€€์Šค์— ๋Œ€ํ•˜์—ฌ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๊ด„ ์‚ฝ์ž… ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

command

๋ช…๋ น์€ ์‹คํ–‰๋  ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด์—๋Š” ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ ์— ๋Œ€ํ•œ 1๊ฐœ ์ด์ƒ์˜ ์ž๋ฆฌ ํ‘œ์‹œ์ž(์˜ˆ: ๋ฌผ์Œํ‘œ)๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

"insert into testy (v1, v2) values (?, ?)"
Copy

seq_of_parameters

์ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ๋ชฉ๋ก ๋˜๋Š” ํŠœํ”Œ์˜ ์‹œํ€€์Šค(๋ชฉ๋ก ๋˜๋Š” ํŠœํ”Œ)์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ ์‹œํ€€์Šค๋Š” ์•„๋ž˜์˜ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ฐ˜ํ™˜:

Cursor ์˜ค๋ธŒ์ ํŠธ์˜ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:
# This example uses qmark (question mark) binding, so
# you must configure the connector to use this binding style.
from snowflake import connector
connector.paramstyle='qmark'

stmt1 = "create table testy (V1 varchar, V2 varchar)"
cs.execute(stmt1)

# A list of lists
sequence_of_parameters1 = [ ['Smith', 'Ann'], ['Jones', 'Ed'] ]
# A tuple of tuples
sequence_of_parameters2 = ( ('Cho', 'Kim'), ('Cooper', 'Pat') )

stmt2 = "insert into testy (v1, v2) values (?, ?)"
cs.executemany(stmt2, sequence_of_parameters1)
cs.executemany(stmt2, sequence_of_parameters2)
Copy

๋‚ด๋ถ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ execute ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋งˆ์ง€๋ง‰ execute ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ ์„ธํŠธ๊ฐ€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ 

executemany ๋ฉ”์„œ๋“œ๋งŒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ๋‹จ์ผ SQL ๋ฌธ์„ ์‹คํ–‰ํ•˜๊ณ  ์—ฌ๋Ÿฌ ๋ฐ”์ธ๋”ฉ ๊ฐ’์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1๊ฐœ์˜ execute ํ˜ธ์ถœ์—์„œ ์„ธ๋ฏธ์ฝœ๋ก ์œผ๋กœ ๊ตฌ๋ถ„๋œ ์—ฌ๋Ÿฌ SQL ๋ฌธ์„ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ๊ฐ ๋ฌธ์— ๋ณ„๋„์˜ execute ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

execute_async(...)ยถ
๋ชฉ์ :

๋น„๋™๊ธฐ ์‹คํ–‰์„ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ช…๋ น์„ ์ค€๋น„ํ•˜์—ฌ ์ œ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์ฟผ๋ฆฌ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์ด ๋ฉ”์„œ๋“œ์—์„œ๋Š” execute() ๋ฉ”์„œ๋“œ์™€ ๋™์ผํ•œ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

Cursor ์˜ค๋ธŒ์ ํŠธ์˜ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

๋น„๋™๊ธฐ ์ฟผ๋ฆฌ์˜ ์˜ˆ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

fetch_arrow_all()ยถ
๋ชฉ์ :

์ด ๋ฉ”์„œ๋“œ๋Š” ์ปค์„œ์—์„œ ๋ชจ๋“  ํ–‰์„ ๊ฐ€์ ธ์™€ PyArrow ํ…Œ์ด๋ธ”๋กœ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

๊ฒฐ๊ณผ ์„ธํŠธ์—์„œ ๋ชจ๋“  ํ–‰์ด ํฌํ•จ๋œ PyArrow ํ…Œ์ด๋ธ”์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ–‰์ด ์—†์œผ๋ฉด None์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์˜ˆ:

Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ๋กœ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์›Œํฌ๋กœ๋“œ ๋ถ„์‚ฐํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

fetch_arrow_batches()ยถ
๋ชฉ์ :

์ด ๋ฉ”์„œ๋“œ๋Š” ์ปค์„œ์—์„œ ํ–‰์˜ ํ•˜์œ„ ์„ธํŠธ๋ฅผ ๊ฐ€์ ธ์™€ PyArrow ํ…Œ์ด๋ธ”๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

๊ฒฐ๊ณผ ์„ธํŠธ์—์„œ ํ•˜์œ„ ์„ธํŠธ๊ฐ€ ํฌํ•จ๋œ PyArrow ํ…Œ์ด๋ธ”์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์ ธ์˜ฌ ํ–‰์ด ๋” ์ด์ƒ ์—†๋Š” ๊ฒฝ์šฐ None์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์˜ˆ:

Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ๋กœ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์›Œํฌ๋กœ๋“œ ๋ถ„์‚ฐํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

get_result_batches()ยถ
๋ชฉ์ :

๊ฒฐ๊ณผ ์„ธํŠธ์—์„œ ํ–‰์˜ ํ•˜์œ„ ์„ธํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ResultBatch ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

ResultBatch ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰์„ ๋งˆ์น˜์ง€ ์•Š์•˜๋‹ค๋ฉด None ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ๋กœ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์›Œํฌ๋กœ๋“œ ๋ถ„์‚ฐํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

get_results_from_sfqid(query_id)ยถ
๋ชฉ์ :

๋น„๋™๊ธฐ ์ฟผ๋ฆฌ ๋„๋Š” ์ด์ „์— ์ œ์ถœํ•œ ๋น„๋™๊ธฐ ์ฟผ๋ฆฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

query_id

์ฟผ๋ฆฌ์˜ ID์ž…๋‹ˆ๋‹ค. Snowflake ์ฟผ๋ฆฌ ID ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์˜ˆ:

์ฟผ๋ฆฌ ID๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

fetchone()ยถ
๋ชฉ์ :

์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์„ธํŠธ์˜ ๋‹ค์Œ ํ–‰์„ ๊ฐ€์ ธ์˜ค๊ณ  ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ๋‹จ์ผ ์‹œํ€€์Šค/dict ๋˜๋Š” None ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

fetchmany([size=cursor.arraysize])ยถ
๋ชฉ์ :

์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์„ธํŠธ์˜ ๋‹ค์Œ ํ–‰์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹œํ€€์Šค/dict์˜ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ–‰์ด ๋” ์ด์ƒ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ๋นˆ ์‹œํ€€์Šค๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

fetchall()ยถ
๋ชฉ์ :

์ฟผ๋ฆฌ ๊ฒฐ๊ณผ ์„ธํŠธ์˜ ๋ชจ๋“  ๋˜๋Š” ๋‚˜๋จธ์ง€ ํ–‰์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹œํ€€์Šค/dict์˜ ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

fetch_pandas_all()ยถ
๋ชฉ์ :

์ด ๋ฉ”์„œ๋“œ๋Š” ์ปค์„œ์—์„œ ๋ชจ๋“  ํ–‰์„ ๊ฐ€์ ธ์™€ pandas DataFrame์œผ๋กœ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

๊ฒฐ๊ณผ ์„ธํŠธ์—์„œ ๋ชจ๋“  ํ–‰์ด ํฌํ•จ๋œ DataFrame์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

pandas ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ pandas DataFrame ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

ํ–‰์ด ์—†์œผ๋ฉด None ์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋ฒ• ๋…ธํŠธ:
  • ์ด ๋ฉ”์„œ๋“œ๋Š” pandas์˜ read_sql() ๋ฉ”์„œ๋“œ๋ฅผ ์™„์ „ํ•˜๊ฒŒ ๋Œ€์ฒดํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด SELECT ์ฟผ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋ฐ์ดํ„ฐ๋ฅผ pandas DataFrame์— ์ €์žฅํ•˜๋Š” ์ž‘์—…์„ ๋น ๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ˜„์žฌ ์ด ๋ฉ”์„œ๋“œ๋Š” SELECT ๋ฌธ์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:
ctx = snowflake.connector.connect(
          host=host,
          user=user,
          password=password,
          account=account,
          warehouse=warehouse,
          database=database,
          schema=schema,
          protocol='https',
          port=port)

# Create a cursor object.
cur = ctx.cursor()

# Execute a statement that will generate a result set.
sql = "select * from t"
cur.execute(sql)

# Fetch the result set from the cursor and deliver it as the pandas DataFrame.
df = cur.fetch_pandas_all()

# ...
Copy
fetch_pandas_batches()ยถ
๋ชฉ์ :

์ด ๋ฉ”์„œ๋“œ๋Š” ์ปค์„œ์—์„œ ํ–‰์˜ ํ•˜์œ„ ์„ธํŠธ๋ฅผ ๊ฐ€์ ธ์™€ pandas DataFrame์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

๊ฒฐ๊ณผ ์„ธํŠธ์—์„œ ํ•˜์œ„ ์„ธํŠธ๊ฐ€ ํฌํ•จ๋œ DataFrame์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

pandas ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ pandas DataFrame ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๊ฐ€์ ธ์˜ฌ ํ–‰์ด ๋” ์ด์ƒ ์—†๋Š” ๊ฒฝ์šฐ None ์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋ฒ• ๋…ธํŠธ:
  • ๊ฒฐ๊ณผ ์„ธํŠธ์˜ ํ–‰ ์ˆ˜ ๋ฐ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์— ์ง€์ •๋œ ํ–‰ ์ˆ˜์— ๋”ฐ๋ผ, ์ด ๋ฉ”์„œ๋“œ๋ฅผ ๋‘ ๋ฒˆ ์ด์ƒ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๊ฑฐ๋‚˜ ๋ชจ๋‘ ์ ํ•ฉํ•œ ๊ฒฝ์šฐ ๋‹จ์ผ ์ผ๊ด„ ์ฒ˜๋ฆฌ์—์„œ ๋ชจ๋“  ํ–‰์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด ๋ฉ”์„œ๋“œ๋Š” pandas์˜ read_sql() ๋ฉ”์„œ๋“œ๋ฅผ ์™„์ „ํ•˜๊ฒŒ ๋Œ€์ฒดํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด SELECT ์ฟผ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋ฐ์ดํ„ฐ๋ฅผ pandas DataFrame์— ์ €์žฅํ•˜๋Š” ์ž‘์—…์„ ๋น ๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ˜„์žฌ ์ด ๋ฉ”์„œ๋“œ๋Š” SELECT ๋ฌธ์—์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:
ctx = snowflake.connector.connect(
          host=host,
          user=user,
          password=password,
          account=account,
          warehouse=warehouse,
          database=database,
          schema=schema,
          protocol='https',
          port=port)

# Create a cursor object.
cur = ctx.cursor()

# Execute a statement that will generate a result set.
sql = "select * from t"
cur.execute(sql)

# Fetch the result set from the cursor and deliver it as the pandas DataFrame.
for df in cur.fetch_pandas_batches():
    my_dataframe_processing_function(df)

# ...
Copy
__iter__()ยถ

์ปค์„œ๊ฐ€ ๋ฐ˜๋ณต ํ”„๋กœํ† ์ฝœ๊ณผ ํ˜ธํ™˜๋  ์ˆ˜ ์žˆ๋„๋ก ์ž์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์†์„ฑยถ

descriptionยถ

๊ฒฐ๊ณผ ์„ธํŠธ์˜ ์—ด์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

์ด ์†์„ฑ์€ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด execute() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ํ›„์— ์„ค์ •๋ฉ๋‹ˆ๋‹ค. (2.4.6 ์ด์ƒ ๋ฒ„์ „์—์„œ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  describe() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ด ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

์ด ์†์„ฑ์€ ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

  • 2.4.5 ์ดํ•˜ ๋ฒ„์ „: ์ด ์†์„ฑ์€ ํŠœํ”Œ์˜ ๋ชฉ๋ก์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

  • 2.4.6 ์ด์ƒ ๋ฒ„์ „: ์ด ์†์„ฑ์€ ResultMetadata ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชฉ๋ก์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

๊ฐ ํŠœํ”Œ ๋˜๋Š” ResultMetadata ์˜ค๋ธŒ์ ํŠธ์—๋Š” ๊ฒฐ๊ณผ ์„ธํŠธ์˜ ์—ด์„ ์„ค๋ช…ํ•˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ธ๋ฑ์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ฑฐ๋‚˜ 2.4.6 ์ด์ƒ ๋ฒ„์ „์˜ ๊ฒฝ์šฐ ResultMetadata ์˜ค๋ธŒ์ ํŠธ ์†์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ’์˜ ์ธ๋ฑ์Šค

ResultMetadata ์†์„ฑ

์„ค๋ช…

0

name

์—ด ์ด๋ฆ„.

1

type_code

๋‚ด๋ถ€ ํƒ€์ž… ์ฝ”๋“œ.

2

display_size

(์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ. ๋‚ด๋ถ€_ํฌ๊ธฐ์™€ ๋™์ผ.)

3

internal_size

๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ.

4

precision

์ˆซ์ž ๋ฐ์ดํ„ฐ์˜ ์ „์ฒด ์ž๋ฆฟ์ˆ˜.

5

scale

์ˆซ์ž ๋ฐ์ดํ„ฐ์˜ ์†Œ์ˆ˜ ์ž๋ฆฟ์ˆ˜์ž…๋‹ˆ๋‹ค.

6

is_nullable

์—ด ๋˜๋Š” False ์—์„œ NULL ๊ฐ’์ด ํ—ˆ์šฉ๋˜๋Š” ๊ฒฝ์šฐ True.

์ด ์†์„ฑ์„ ๊ฐ€์ ธ์˜ค๋Š” ์˜ˆ๋Š” ์—ด ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

rowcountยถ

์ƒ์„ฑ๋œ ๋งˆ์ง€๋ง‰ execute ์—์„œ ํ–‰์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ž…๋‹ˆ๋‹ค. execute ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ฐ’์€ -1 ๋˜๋Š” None ์ž…๋‹ˆ๋‹ค.

sfqidยถ

์‹คํ–‰๋œ ๋งˆ์ง€๋ง‰ execute ๋˜๋Š” execute_async ์—์„œ Snowflake ์ฟผ๋ฆฌ ID๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

arraysizeยถ

fetchmany() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ ๋ฒˆ์— ๊ฐ€์ ธ์˜ฌ ํ–‰์˜ ์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋Š” ์ฝ๊ธฐ/์“ฐ๊ธฐ ์†์„ฑ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์„ 1 ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ํ•œ ๋ฒˆ์— 1๊ฐœ์˜ ํ–‰์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

connectionยถ

์ปค์„œ๊ฐ€ ์ƒ์„ฑ๋œ Connection ์˜ค๋ธŒ์ ํŠธ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

messages

์ปค์„œ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ์ˆ˜์‹ ๋œ ๋ชจ๋“  ๋ฉ”์‹œ์ง€์— ๋Œ€ํ•œ ์‹œํ€€์Šค๋ฅผ ํฌํ•จํ•˜๋Š” ์˜ค๋ธŒ์ ํŠธ(์˜ˆ์™ธ ํด๋ž˜์Šค, ์˜ˆ์™ธ ๊ฐ’)๋ฅผ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.

fetch*() ํ˜ธ์ถœ์„ ์ œ์™ธํ•˜๊ณ  ๋ชฉ๋ก์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ž๋™์œผ๋กœ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

errorhandler

์˜ค๋ฅ˜ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋  ๋•Œ ํ˜ธ์ถœํ•  ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ฝ๊ธฐ/์“ฐ๊ธฐ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

์ด ์ฒ˜๋ฆฌ๊ธฐ๋Š” ๋‹ค์Œ ์ธ์ž๋ฅผ ํ—ˆ์šฉํ•˜๊ณ  Python์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

errorhandler(connection, cursor, errorclass, errorvalue)

์œ ํ˜• ์ฝ”๋“œยถ

Cursor ์˜ค๋ธŒ์ ํŠธ์—์„œ description ์†์„ฑ ๋ฐ describe() ๋ฉ”์„œ๋“œ๋Š” ๊ฒฐ๊ณผ ์„ธํŠธ์˜ ์—ด์„ ์„ค๋ช…ํ•˜๋Š” ํŠœํ”Œ์˜ ๋ชฉ๋ก(๋˜๋Š” 2.4.6 ์ด์ƒ ๋ฒ„์ „์˜ ๊ฒฝ์šฐ ResultMetadata ์˜ค๋ธŒ์ ํŠธ)์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํŠœํ”Œ์—์„œ ์ธ๋ฑ์Šค 1 ์˜ ๊ฐ’(ResultMetadata ์˜ค๋ธŒ์ ํŠธ์˜ type_code ์†์„ฑ)์€ ์—ด ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ์—์„œ ํƒ€์ž… ์ฝ”๋“œ์— ๋”ฐ๋ผ ๋ฌธ์ž์—ด ํ‘œํ˜„์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋งคํ•‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํƒ€์ž…_์ฝ”๋“œ

๋ฌธ์ž์—ด ํ‘œํ˜„

๋ฐ์ดํ„ฐ ํƒ€์ž…

0

FIXED

NUMBER/INT

1

REAL

REAL

2

TEXT

VARCHAR/STRING

3

DATE

DATE

4

TIMESTAMP

TIMESTAMP

5

VARIANT

VARIANT

6

TIMESTAMP_LTZ

TIMESTAMP_LTZ

7

TIMESTAMP_TZ

TIMESTAMP_TZ

8

TIMESTAMP_NTZ

TIMESTAMP_TZ

9

OBJECT

OBJECT

10

ARRAY

ARRAY

11

BINARY

BINARY

12

TIME

TIME

13

BOOLEAN

BOOLEAN

14

GEOGRAPHY

GEOGRAPHY

15

GEOMETRY

GEOMETRY

16

VECTOR

VECTOR

qmark ๋ฐ numeric ๋ฐ”์ธ๋”ฉ์šฉ ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋งคํ•‘ยถ

paramstyle ์ด "qmark" ๋˜๋Š” "numeric" ์ธ ๊ฒฝ์šฐ์—๋Š” Python์—์„œ Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ๋งคํ•‘์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

Python ๋ฐ์ดํ„ฐ ํƒ€์ž…

Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž…

int

NUMBER(38, 0)

long

NUMBER(38, 0)

decimal

NUMBER(38, <์†Œ์ˆ˜ ์ž๋ฆฟ์ˆ˜>)

float

REAL

str

TEXT

unicode

TEXT

bytes

BINARY

bytearray

BINARY

bool

BOOLEAN

date

DATE

time

TIME

timedelta

TIME

datetime

TIMESTAMP_NTZ

struct_time

TIMESTAMP_NTZ

๋‹ค๋ฅธ Snowflake ํƒ€์ž…์œผ๋กœ ๋งคํ•‘(์˜ˆ: datetime ์„ TIMESTAMP_LTZ ๋กœ)ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž… ๋‹ค์Œ์— ๊ฐ’์ด ์˜ค๋Š” ํ˜•์‹์œผ๋กœ ๊ตฌ์„ฑ๋œ ํŠœํ”Œ๋กœ Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋Š” TIMESTAMP๋ฅผ ์‚ฌ์šฉํ•œ ๋‚ ์งœ/์‹œ๊ฐ„ ๋ฐ”์ธ๋”ฉ ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์˜ค๋ธŒ์ ํŠธ: Exceptionยถ

PEP-249๋Š” ์˜ค๋ฅ˜ ๋˜๋Š” ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ Python์šฉ Snowflake Connector์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ด๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ฝ”๋“œ ์‹คํ–‰์˜ ๊ณ„์† ๋˜๋Š” ์ค‘์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ PEP-249 ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ฉ”์„œ๋“œยถ

Exception ์˜ค๋ธŒ์ ํŠธ์šฉ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์†์„ฑยถ

errnoยถ

Snowflake DB ์˜ค๋ฅ˜ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

msgยถ

์˜ค๋ฅ˜ ์ฝ”๋“œ, SQL ์ƒํƒœ ์ฝ”๋“œ ๋ฐ ์ฟผ๋ฆฌ ID ๋“ฑ์˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์ž…๋‹ˆ๋‹ค.

raw_msgยถ

์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์ž…๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ์ฝ”๋“œ, SQL ์ƒํƒœ ์ฝ”๋“œ ๋˜๋Š” ์ฟผ๋ฆฌ ID๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

sqlstateยถ

ANSI ๊ทœ๊ฒฉ SQL ์ƒํƒœ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค

sfqid

Snowflake ์ฟผ๋ฆฌ ID์ž…๋‹ˆ๋‹ค.

์˜ค๋ธŒ์ ํŠธ ResultBatchยถ

ResultBatch ์˜ค๋ธŒ์ ํŠธ๋Š” ๊ฒฐ๊ณผ ์„ธํŠธ์—์„œ ํ–‰์˜ ํ•˜์œ„ ์„ธํŠธ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์บก์Аํ™”ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์ž‘์—…์ž ๋˜๋Š” ๋…ธ๋“œ์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ž‘์—…์„ ๋ฐฐํฌ ํ•˜๋ ค๋ฉด Cursor ์˜ค๋ธŒ์ ํŠธ์—์„œ get_result_batches() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ResultBatch ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชฉ๋ก์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ์ž‘์—…์ž ๋˜๋Š” ๋…ธ๋“œ์— ์ด๋Ÿฌํ•œ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์†์„ฑยถ

ํ–‰ ์ˆ˜ยถ

๊ฒฐ๊ณผ ๋ฐฐ์น˜์—์„œ ํ–‰์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

์••์ถ•_ํฌ๊ธฐยถ

๊ฒฐ๊ณผ ๋ฐฐ์น˜์—์„œ (์••์ถ• ์‹œ) ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

๋น„์••์ถ•_ํฌ๊ธฐยถ

๊ฒฐ๊ณผ ๋ฐฐ์น˜์—์„œ (๋น„์••์ถ•) ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ž…๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œยถ

to_arrow()ยถ
๋ชฉ์ :

์ด ๋ฉ”์„œ๋“œ๋Š” ResultBatch ์˜ค๋ธŒ์ ํŠธ์˜ ํ–‰์„ ํฌํ•จํ•˜๋Š” PyArrow ํ…Œ์ด๋ธ”์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

ResultBatch ์˜ค๋ธŒ์ ํŠธ์—์„œ ํ–‰์„ ํฌํ•จํ•˜๋Š” PyArrow ํ…Œ์ด๋ธ”์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ–‰์ด ์—†์œผ๋ฉด None์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

to_pandas()ยถ
๋ชฉ์ :

์ด ๋ฉ”์„œ๋“œ๋Š” ResultBatch ์˜ค๋ธŒ์ ํŠธ์˜ ํ–‰์„ ํฌํ•จํ•˜๋Š” pandas DataFrame์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

ResultBatch ์˜ค๋ธŒ์ ํŠธ์—์„œ ํ–‰์„ ํฌํ•จํ•˜๋Š” pandas DataFrame์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ–‰์ด ์—†์œผ๋ฉด ๋นˆ pandas DataFrame์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋ธŒ์ ํŠธ: ResultMetadataยถ

ResultMetadata ์˜ค๋ธŒ์ ํŠธ๋Š” ๊ฒฐ๊ณผ ์„ธํŠธ ๋‚ด์˜ ์—ด์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์˜ค๋ธŒ์ ํŠธ์˜ ๋ชฉ๋ก์€ Cursor ์˜ค๋ธŒ์ ํŠธ์˜ description ์†์„ฑ ๋ฐ describe ๋ฉ”์„œ๋“œ์— ์˜ํ•ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

์ด ์˜ค๋ธŒ์ ํŠธ๋Š” Python์šฉ Snowflake ์ปค๋„ฅํ„ฐ์˜ 2.4.6 ๋ฒ„์ „์—์„œ ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œยถ

์—†์Šต๋‹ˆ๋‹ค.

์†์„ฑยถ

nameยถ

์—ด์˜ ์ด๋ฆ„

type_codeยถ

๋‚ด๋ถ€ ํƒ€์ž… ์ฝ”๋“œ.

display_sizeยถ

์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€_ํฌ๊ธฐ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

internal_sizeยถ

๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ.

precisionยถ

์ˆซ์ž ๋ฐ์ดํ„ฐ์˜ ์ „์ฒด ์ž๋ฆฟ์ˆ˜.

scaleยถ

์ˆซ์ž ๋ฐ์ดํ„ฐ์˜ ์†Œ์ˆ˜ ์ž๋ฆฟ์ˆ˜์ž…๋‹ˆ๋‹ค.

is_nullableยถ

์—ด ๋˜๋Š” False ์—์„œ NULL ๊ฐ’์ด ํ—ˆ์šฉ๋˜๋Š” ๊ฒฝ์šฐ True.

๋ชจ๋“ˆ: snowflake.connector.constantsยถ

snowflake.connector.constants ๋ชจ๋“ˆ์€ API์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ƒ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

์—ด๊ฑฐํ˜•ยถ

class QueryStatusยถ

๋น„๋™๊ธฐ ์ฟผ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ์ด ์—ด๊ฑฐํ˜•์— ํฌํ•จ๋˜๋Š” ์ƒ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์—ด๊ฑฐํ˜• ์ƒ์ˆ˜

์„ค๋ช…

RUNNING

์ฟผ๋ฆฌ๋ฅผ ์•„์ง ์‹คํ–‰ํ•˜๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

ABORTING

์„œ๋ฒ„ ์ธก์—์„œ ์ฟผ๋ฆฌ๋ฅผ ์ค‘๋‹จํ•˜๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

SUCCESS

์ฟผ๋ฆฌ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

FAILED_WITH_ERROR

์ฟผ๋ฆฌ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ์ง€๋งŒ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.

QUEUED

์‹คํ–‰์„ ์œ„ํ•ด ์ฟผ๋ฆฌ๊ฐ€ ํ์—์„œ ๋Œ€๊ธฐ ์ค‘์ด๋ฉฐ(์ฆ‰, ์•„์ง ์‹คํ–‰์ด ์‹œ์ž‘๋˜์ง€ ์•Š์Œ), ์ด๋Ÿฌํ•œ ์ผ๋ฐ˜์ ์ธ ์ด์œ ๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋Œ€๊ธฐ ์ค‘์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

DISCONNECTED

์„ธ์…˜์˜ ์—ฐ๊ฒฐ์ด ๋Š๊ฒผ์Šต๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ์˜ ์ƒํƒœ๊ฐ€ ๊ณง โ€œFAILED_WITH_ERRORโ€๋กœ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค.

RESUMING_WAREHOUSE

์›จ์–ดํ•˜์šฐ์Šค๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์ง€๋งŒ ์•„์ง ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰ ์ค‘์ด ์•„๋‹™๋‹ˆ๋‹ค.

BLOCKED

๋ฌธ์ด ๋‹ค๋ฅธ ๋ฌธ์ด ์ž ๊ทผ ๋ฆฌ์†Œ์Šค๋ฅผ ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

NO_DATA

๋ฌธ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์•„์ง ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ผ๋ฐ˜์ ์ธ ์ด์œ ๋Š” ๋ฌธ์˜ ์‹คํ–‰์ด ์•„์ง ์‹œ์ž‘๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“ˆ: snowflake.connector.pandas_toolsยถ

snowflake.connector.pandas_tools ๋ชจ๋“ˆ์€ pandas ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ž์„ธํ•œ ๋‚ด์šฉ์€ pandas ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค๋ช…์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

ํ•จ์ˆ˜ยถ

write_pandas(parameters...)ยถ
๋ชฉ์ :

pandas DataFrame์„ Snowflake ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ํ…Œ์ด๋ธ”์— ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ ํ…Œ์ด๋ธ”์— ์ž‘์„ฑํ•˜๋ ค๋ฉด, ์ด ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ Parquet ํŒŒ์ผ์— ์ €์žฅํ•˜๊ณ  PUT ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ํŒŒ์ผ์„ ์ž„์‹œ ์Šคํ…Œ์ด์ง€์— ์—…๋กœ๋“œํ•˜๋ฉฐ COPY INTO <ํ…Œ์ด๋ธ”> ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์—์„œ ํ…Œ์ด๋ธ”๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ํ•จ์ˆ˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ PUT ๋ฐ COPY INTO <ํ…Œ์ด๋ธ” > ๋ฌธ์˜ ์‹คํ–‰ ๋ฐฉ๋ฒ•์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์œ ํšจํ•œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜:

๋งค๊ฐœ ๋ณ€์ˆ˜

ํ•„์ˆ˜

์„ค๋ช…

conn

์˜ˆ

Snowflake ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ์˜ ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•˜๋Š” Connection ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค.

df

์˜ˆ

ํ…Œ์ด๋ธ”๋กœ ๋ณต์‚ฌ๋  ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ pandas.DataFrame ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค.

table_name

์˜ˆ

๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ•  ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

database

ํ…Œ์ด๋ธ”์ด ํฌํ•จ๋œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ํ•จ์ˆ˜๋Š” ํ˜„์žฌ ์„ธ์…˜์—์„œ ์‚ฌ์šฉ ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ : ์ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋ฉด schema ๋งค๊ฐœ ๋ณ€์ˆ˜๋„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

schema

ํ…Œ์ด๋ธ”์ด ํฌํ•จ๋œ ์Šคํ‚ค๋งˆ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ํ•จ์ˆ˜๋Š” ํ˜„์žฌ ์„ธ์…˜์—์„œ ์‚ฌ์šฉ ์ค‘์ธ ์Šคํ‚ค๋งˆ์— ํ…Œ์ด๋ธ”์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

chunk_size

ํ•œ ๋ฒˆ์— ์‚ฝ์ž…ํ•  ์š”์†Œ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด ํ•จ์ˆ˜๋Š” 1๊ฐœ ์ฒญํฌ์— ํ•œ ๋ฒˆ์— ๋ชจ๋“  ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

compression

Parquet ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ์••์ถ• ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ์••์ถ•์„ ํ–ฅ์ƒํ•˜๊ธฐ ์œ„ํ•ด "gzip" ์„ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ๋น ๋ฅธ ์••์ถ•์„ ์œ„ํ•ด "snappy" ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, ์ด ํ•จ์ˆ˜์—์„œ๋Š” "gzip" ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

on_error

์˜ค๋ฅ˜๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ON_ERROR ๋ณต์‚ฌ ์˜ต์…˜ ์— ์„ค๋ช…๋œ ๋ฌธ์ž์—ด ๊ฐ’ ์ค‘ 1๊ฐœ๋กœ ์ด ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, ์ด ํ•จ์ˆ˜์—์„œ๋Š” "ABORT_STATEMENT" ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

parallel

Parquet ํŒŒ์ผ์„ ์ž„์‹œ ์Šคํ…Œ์ด์ง€๋กœ ์—…๋กœ๋“œํ•  ๋•Œ ์‚ฌ์šฉํ•  ์Šค๋ ˆ๋“œ์˜ ๊ฐœ์ˆ˜์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋˜๋Š” ์Šค๋ ˆ๋“œ์˜ ๊ธฐ๋ณธ ๊ฐœ์ˆ˜์™€ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๋ฅผ ์„ ํƒํ•  ๋•Œ์˜ ์ง€์นจ์€ PUT ๋ช…๋ น์˜ ๋ณ‘๋ ฌ ๋งค๊ฐœ ๋ณ€์ˆ˜ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

quote_identifiers

False ์ธ ๊ฒฝ์šฐ, ์ปค๋„ฅํ„ฐ๋Š” ์‹๋ณ„์ž๋ฅผ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์ง€ ์•Š๊ณ  ์‹๋ณ„์ž๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ปค๋„ฅํ„ฐ๋Š” ์‹๋ณ„์ž๋ฅผ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์Šต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜:

(success, num_chunks, num_rows, output) ์˜ ํŠœํ”Œ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ,

  • ํ•จ์ˆ˜์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํ…Œ์ด๋ธ”์— ์ž‘์„ฑํ•˜๋Š” ๋ฐ ์„ฑ๊ณตํ•˜๋ฉด success ์€ True ์ž…๋‹ˆ๋‹ค.

  • num_chunks ๋Š” ํ•จ์ˆ˜์—์„œ ๋ณต์‚ฌํ•œ ๋ฐ์ดํ„ฐ ์ฒญํฌ์˜ ์ˆ˜์ž…๋‹ˆ๋‹ค.

  • num_rows ๋Š” ํ•จ์ˆ˜์—์„œ ์‚ฝ์ž…ํ•œ ํ–‰์˜ ์ˆ˜์ž…๋‹ˆ๋‹ค.

  • output ์€ COPY INTO <ํ…Œ์ด๋ธ”> ๋ช…๋ น์˜ ์ถœ๋ ฅ์ž…๋‹ˆ๋‹ค.

์˜ˆ:

๋‹ค์Œ ์˜ˆ์—์„œ๋Š” pandas DataFrame์—์„œ โ€˜๊ณ ๊ฐโ€™ ํ…Œ์ด๋ธ”๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

import pandas
from snowflake.connector.pandas_tools import write_pandas

# Create the connection to the Snowflake database.
cnx = snowflake.connector.connect(...)

# Create a DataFrame containing data about customers
df = pandas.DataFrame([('Mark', 10), ('Luke', 20)], columns=['name', 'balance'])

# Write the data from the DataFrame to the table named "customers".
success, nchunks, nrows, _ = write_pandas(cnx, df, 'customers')
Copy
pd_writer(parameters...)ยถ
๋ชฉ์ :

pd_writer ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ Snowflake ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์‚ฝ์ž…ํ•˜๊ธฐ ์œ„ํ•œ insertion ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

pandas.DataFrame.to_sql ์„ ํ˜ธ์ถœํ•  ๋•Œ, method=pd_writer ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ pd_writer ๋ฅผ ๋ฐ์ดํ„ฐ ์‚ฝ์ž… ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. (์ฝ”๋“œ์—์„œ pd_writer ๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. to_sql ๋ฉ”์„œ๋“œ๋Š” pd_writer ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉฐ ํ•„์š”ํ•œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.)

์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ฐธ๊ณ 

pandas DataFrame ์˜ ์—ด ์ด๋ฆ„์— ์†Œ๋ฌธ์ž๋งŒ ํฌํ•จ๋œ ๊ฒฝ์šฐ ์—ด ์ด๋ฆ„์„ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ปค๋„ฅํ„ฐ๊ฐ€ ProgrammingError ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

snowflake-sqlalchemy ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•  ๋•Œ ์†Œ๋ฌธ์ž ์—ด ์ด๋ฆ„์„ ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์ง€ ์•Š๋Š” ๋ฐ˜๋ฉด, pd_writer ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์—ด ์ด๋ฆ„์„ ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์Šต๋‹ˆ๋‹ค. COPY INTO ๋ช…๋ น์—์„œ ์—ด ์ด๋ฆ„์ด ๋‹น์—ฐํžˆ ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์ผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํ–ฅํ›„ ๊ฐœ์„  ์‚ฌํ•ญ์€ snowflake-sqlalchemy ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

์˜ˆ:

import pandas as pd
from snowflake.connector.pandas_tools import pd_writer

sf_connector_version_df = pd.DataFrame([('snowflake-connector-python', '1.0')], columns=['NAME', 'NEWEST_VERSION'])

# Specify that the to_sql method should use the pd_writer function
# to write the data from the DataFrame to the table named "driver_versions"
# in the Snowflake database.
sf_connector_version_df.to_sql('driver_versions', engine, index=False, method=pd_writer)

# When the column names consist of only lower case letters, quote the column names
sf_connector_version_df = pd.DataFrame([('snowflake-connector-python', '1.0')], columns=['"name"', '"newest_version"'])
sf_connector_version_df.to_sql('driver_versions', engine, index=False, method=pd_writer)
Copy

pd_writer ํ•จ์ˆ˜์—์„œ๋Š” write_pandas() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DataFrame์˜ ๋ฐ์ดํ„ฐ๋ฅผ Snowflake ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜:

์œ ํšจํ•œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜:

๋งค๊ฐœ ๋ณ€์ˆ˜

ํ•„์ˆ˜

์„ค๋ช…

table

์˜ˆ

ํ…Œ์ด๋ธ”์„ ์œ„ํ•œ pandas.io.sql.SQLTable ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค.

conn

์˜ˆ

Snowflake ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ sqlalchemy.engine.Engine ๋˜๋Š” sqlalchemy.engine.Connection ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค.

keys

์˜ˆ

์‚ฝ์ž…ํ•  ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ํ…Œ์ด๋ธ” ์—ด์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

data_iter

์˜ˆ

์‚ฝ์ž…ํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ํ–‰์˜ ๋ฐ˜๋ณต๊ธฐ์ž…๋‹ˆ๋‹ค.

์˜ˆ:

๋‹ค์Œ ์˜ˆ์—์„œ๋Š” method=pd_writer ๋ฅผ pandas.DataFrame.to_sql ๋ฉ”์„œ๋“œ๋กœ ์ „๋‹ฌํ•˜๊ณ , ์ด ๋ฉ”์„œ๋“œ๋Š” pd_writer ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ pandas DataFrame์˜ ๋ฐ์ดํ„ฐ๋ฅผ Snowflake ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

import pandas
from snowflake.connector.pandas_tools import pd_writer

# Create a DataFrame containing data about customers
df = pandas.DataFrame([('Mark', 10), ('Luke', 20)], columns=['name', 'balance'])

# Specify that the to_sql method should use the pd_writer function
# to write the data from the DataFrame to the table named "customers"
# in the Snowflake database.
df.to_sql('customers', engine, index=False, method=pd_writer)
Copy

๋‚ ์งœ ๋ฐ ํƒ€์ž„์Šคํƒฌํ”„ ์ง€์›ยถ

Snowflake๋Š” ์—ฌ๋Ÿฌ DATE ๋ฐ TIMESTAMP ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ์ง€์›ํ•˜๋ฉฐ, Snowflake ์ปค๋„ฅํ„ฐ๋Š” ์—…๋ฐ์ดํŠธ ๋ฐ ํŽ˜์น˜ ์ž‘์—…์„ ์œ„ํ•ด ๋„ค์ดํ‹ฐ๋ธŒ datetime ๋ฐ date ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐยถ

๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด Python ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž…

Python ๋ฐ์ดํ„ฐ ํƒ€์ž…

๋™์ž‘

TIMESTAMP_TZ

tzinfo ํฌํ•จ ๋‚ ์งœ/์‹œ๊ฐ„

ํƒ€์ž„์กด ์˜คํ”„์…‹ ๋“ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  tzinfo ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ํฌํ•จ๋œ datetime ์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

TIMESTAMP_LTZ, TIMESTAMP

tzinfo ํฌํ•จ ๋‚ ์งœ/์‹œ๊ฐ„

๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  datetime ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€ํ™˜ํ•˜๋ฉฐ TIMESTAMP_TYPE_MAPPING ์„ธ์…˜ ๋งค๊ฐœ ๋ณ€์ˆ˜์— ๋”ฐ๋ผ tzinfo ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

TIMESTAMP_NTZ

๋‚ ์งœ/์‹œ๊ฐ„

๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  datetime ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž„์กด ์ •๋ณด๊ฐ€ ์˜ค๋ธŒ์ ํŠธ์— ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

DATE

๋‚ ์งœ

๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  date ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž„์กด ์ •๋ณด๊ฐ€ ์˜ค๋ธŒ์ ํŠธ์— ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ 

tzinfo ๋Š” UTC ์˜คํ”„์…‹ ๊ธฐ๋ฐ˜ ํƒ€์ž„์กด ์˜ค๋ธŒ์ ํŠธ์ด๋ฉฐ IANA ํƒ€์ž„์กด ์ด๋ฆ„์ด ์•„๋‹™๋‹ˆ๋‹ค. ํƒ€์ž„์กด ์ด๋ฆ„์€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋™๋“ฑํ•œ ์˜คํ”„์…‹ ๊ธฐ๋ฐ˜ ํƒ€์ž„์กด ์˜ค๋ธŒ์ ํŠธ๋Š” ๋™์ผํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธํ•˜๊ธฐยถ

๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ Python ๋ฐ์ดํ„ฐ ํƒ€์ž…์ด Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

Python ๋ฐ์ดํ„ฐ ํƒ€์ž…

Snowflake ๋ฐ์ดํ„ฐ ํƒ€์ž…

๋™์ž‘

๋‚ ์งœ/์‹œ๊ฐ„

TIMESTAMP_TZ, TIMESTAMP_LTZ, TIMESTAMP_NTZ, DATE

๋‚ ์งœ/์‹œ๊ฐ„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ YYYY-MM-DD HH24:MI:SS.FF TZH:TZM ํ˜•์‹์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž„์กด ์˜คํ”„์…‹์ด ์ œ๊ณต๋˜์ง€ ์•Š์œผ๋ฉด ๋ฌธ์ž์—ด์€ YYYY-MM-DD HH24:MI:SS.FF ์˜ ํ˜•์‹์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. datetime ์˜ค๋ธŒ์ ํŠธ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ tzinfo ๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

struct_time

TIMESTAMP_TZ, TIMESTAMP_LTZ, TIMESTAMP_NTZ, DATE

struct_time ์˜ค๋ธŒ์ ํŠธ๋ฅผ YYYY-MM-DD HH24:MI:SS.FF TZH:TZM ํ˜•์‹์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž„์กด ์ •๋ณด๋ฅผ time.timezone ์—์„œ ๊ฐ€์ ธ์˜ค๋ฉฐ, ์—ฌ๊ธฐ์—๋Š” UTC ๊ธฐ์ค€ ํƒ€์ž„์กด ์˜คํ”„์…‹์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. time.timezone ์— ๋Œ€ํ•œ TZ ๋ณ€์ˆ˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚ ์งœ

TIMESTAMP_TZ, TIMESTAMP_LTZ, TIMESTAMP_NTZ, DATE

๋‚ ์งœ ์˜ค๋ธŒ์ ํŠธ๋ฅผ YYYY-MM-DD ํ˜•์‹์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž„์กด์€ ๊ณ ๋ ค๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‹œ๊ฐ„

TIMESTAMP_TZ, TIMESTAMP_LTZ, TIMESTAMP_NTZ, DATE

์‹œ๊ฐ„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ HH24:MI:SS.FF ํ˜•์‹์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž„์กด์€ ๊ณ ๋ ค๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

timedelta

TIMESTAMP_TZ, TIMESTAMP_LTZ, TIMESTAMP_NTZ, DATE

timedelta ์˜ค๋ธŒ์ ํŠธ๋ฅผ HH24:MI:SS.FF ํ˜•์‹์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์ž„์กด์€ ๊ณ ๋ ค๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.