Python์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ๋ฐ ์–ธ๋กœ๋”ฉ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌยถ

Python์„ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์—์„œ ์™ธ๋ถ€ ๋ณผ๋ฅจ, ํŒŒ์ดํ”„, ์Šคํ…Œ์ด์ง€๋ฅผ ํฌํ•จํ•œ ๋ฆฌ์†Œ์Šค์˜ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ๋ฐ ์–ธ๋กœ๋”ฉ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „์ œ ์กฐ๊ฑดยถ

์ด ํ•ญ๋ชฉ์˜ ์˜ˆ์ œ์—์„œ๋Š” Snowflake์™€ ์—ฐ๊ฒฐํ•˜๊ณ  Snowflake Python APIs ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Root ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์ฝ”๋“œ๋Š” ๊ตฌ์„ฑ ํŒŒ์ผ์— ์ •์˜๋œ ์—ฐ๊ฒฐ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

from snowflake.core import Root
from snowflake.snowpark import Session

session = Session.builder.config("connection_name", "myconnection").create()
root = Root(session)
Copy

ํ•ด๋‹น ์ฝ”๋“œ์—์„œ๋Š” ๊ฒฐ๊ณผ Session ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ API์˜ ์œ ํ˜•๊ณผ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Root ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Snowflake Python APIs ์„ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์— ์—ฐ๊ฒฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์Šคํ…Œ์ด์ง€ ๊ด€๋ฆฌํ•˜๊ธฐยถ

ํด๋ผ์šฐ๋“œ ์ €์žฅ์†Œ์˜ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์˜ ์œ„์น˜์ธ Snowflake ์Šคํ…Œ์ด์ง€๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ…Œ์ด์ง€์— ๋Œ€ํ•œ ๊ฐœ์š”๋Š” ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ๊ฐœ์š” ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Snowflake Python APIs ์€ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ๋ณ„๊ฐœ ์œ ํ˜•์˜ ์Šคํ…Œ์ด์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

  • Stage: ์Šคํ…Œ์ด์ง€์˜ ์ด๋ฆ„, ์•”ํ˜ธํ™” ์œ ํ˜•, ์ž๊ฒฉ ์ฆ๋ช…, ๋””๋ ‰ํ„ฐ๋ฆฌ ํ…Œ์ด๋ธ” ์„ค์ • ๋“ฑ ์†์„ฑ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

  • StageResource: ํ•ด๋‹น Stage ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ์Šคํ…Œ์ด์ง€์— ํŒŒ์ผ์„ ์—…๋กœ๋“œ ๋ฐ ๋ชฉ๋ก์œผ๋กœ ๋งŒ๋“ค๊ณ , ์Šคํ…Œ์ด์ง€๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

์Šคํ…Œ์ด์ง€ ๋งŒ๋“ค๊ธฐยถ

์Šคํ…Œ์ด์ง€๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋จผ์ € Stage ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ API Root ์˜ค๋ธŒ์ ํŠธ์—์„œ StageCollection ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. StageCollection.create ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์— ์ƒˆ ์Šคํ…Œ์ด์ง€๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ์•”ํ˜ธํ™” ์œ ํ˜•์ด SNOWFLAKE_SSE (์„œ๋ฒ„ ์ธก ์•”ํ˜ธํ™”๋งŒ ํ•ด๋‹น)์ธ my_stage ๋ผ๋Š” ์Šคํ…Œ์ด์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” Stage ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

from snowflake.core.stage import Stage, StageEncryption

my_stage = Stage(
  name="my_stage",
  encryption=StageEncryption(type="SNOWFLAKE_SSE")
)
stages = root.databases["my_db"].schemas["my_schema"].stages
stages.create(my_stage)
Copy

์ด ์ฝ”๋“œ๋Š” StageCollection ๋ณ€์ˆ˜ stages ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  StageCollection.create ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์— ์ƒˆ ์Šคํ…Œ์ด์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์Šคํ…Œ์ด์ง€ ์„ธ๋ถ€ ์ •๋ณด ์–ป๊ธฐยถ

Stage ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” StageResource.fetch ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์Šคํ…Œ์ด์ง€์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” my_stage ์Šคํ…Œ์ด์ง€์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

my_stage = root.databases["my_db"].schemas["my_schema"].stages["my_stage"].fetch()
print(my_stage.to_dict())
Copy

๋ชฉ๋ก ์Šคํ…Œ์ด์ง€ยถ

Stage ์˜ค๋ธŒ์ ํŠธ์˜ PagedIter ๋ฐ˜๋ณต๊ธฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” StageCollection.iter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํ…Œ์ด์ง€๋ฅผ ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ์ด๋ฆ„์— my ํ…์ŠคํŠธ๊ฐ€ ํฌํ•จ๋œ ์Šคํ…Œ์ด์ง€๋ฅผ ๋‚˜์—ดํ•˜๊ณ  ๊ฐ ์Šคํ…Œ์ด์ง€์˜ ์ด๋ฆ„์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

from snowflake.core.stage import StageCollection

stages: StageCollection = root.databases["my_db"].schemas["my_schema"].stages
stage_iter = stages.iter(like="my%")  # returns a PagedIter[Stage]
for stage_obj in stage_iter:
  print(stage_obj.name)
Copy

์Šคํ…Œ์ด์ง€ ์ž‘์—… ์ˆ˜ํ–‰ํ•˜๊ธฐยถ

์Šคํ…Œ์ด์ง€์— ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๊ณ  ์Šคํ…Œ์ด์ง€์— ํŒŒ์ผ์„ ๋ชฉ๋ก์œผ๋กœ ๋‚˜์—ดํ•˜๋Š” ๋“ฑ ์ผ๋ฐ˜์ ์ธ ์Šคํ…Œ์ด์ง€ ์ž‘์—…์„ StageResource ์˜ค๋ธŒ์ ํŠธ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ…Œ์ด์ง€ ๋ฆฌ์†Œ์Šค๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋ถ€ ์ž‘์—…์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. ์ง€์ •๋œ ์ž๋™ ์••์ถ• ๋ฐ ๋ฎ์–ด์“ฐ๊ธฐ ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ my-file.yaml ํŒŒ์ผ์„ my_stage ์Šคํ…Œ์ด์ง€์— ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

  2. ํŒŒ์ผ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์—…๋กœ๋“œ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์Šคํ…Œ์ด์ง€์— ์žˆ๋Š” ๋ชจ๋“  ํŒŒ์ผ์„ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.

  3. ์Šคํ…Œ์ด์ง€๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

my_stage_res = root.databases["my_db"].schemas["my_schema"].stages["my_stage"]

my_stage_res.put("./my-file.yaml", "/", auto_compress=False, overwrite=True)

stageFiles = root.databases["my_db"].schemas["my_schema"].stages["my_stage"].list_files()
for stageFile in stageFiles:
  print(stageFile)

my_stage_res.drop()
Copy

ํŒŒ์ดํ”„ ๊ด€๋ฆฌํ•˜๊ธฐยถ

Snowpipe๊ฐ€ ์ˆ˜์ง‘ ํ์—์„œ ํ…Œ์ด๋ธ”๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” COPY INTO ๋ฌธ์ด ํฌํ•จ๋œ ๋ช…๋ช…๋œ ์ผ๊ธ‰ Snowflake ์˜ค๋ธŒ์ ํŠธ์ธ Snowflake ํŒŒ์ดํ”„๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ดํ”„ ๊ฐœ์š”๋Š” Snowpipe ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Snowflake Python APIs ์€ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ๋ณ„๊ฐœ ์œ ํ˜•์˜ ํŒŒ์ดํ”„๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

  • Pipe: ์ด๋ฆ„๊ณผ ๊ฐ™์€ ํŒŒ์ดํ”„์˜ ์†์„ฑ๊ณผ Snowpipe์—์„œ ์‚ฌ์šฉํ•  COPY INTO ๋ฌธ์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  • PipeResource: ํ•ด๋‹น Pipe ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ์Šคํ…Œ์ด์ง•๋œ ๋ฐ์ดํ„ฐ ํŒŒ์ผ๋กœ ํŒŒ์ดํ”„๋ฅผ ์ƒˆ๋กœ ๊ณ ์น˜๊ณ , ํŒŒ์ดํ”„๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„ ๋งŒ๋“ค๊ธฐยถ

ํŒŒ์ดํ”„๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋จผ์ € Pipe ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ API Root ์˜ค๋ธŒ์ ํŠธ์—์„œ PipeCollection ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. PipeCollection.create ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์— ์ƒˆ ํŒŒ์ดํ”„๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ์ง€์ •๋œ COPY INTO ๋ฌธ์œผ๋กœ my_pipe ํŒŒ์ดํ”„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” Pipe ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

from snowflake.core.pipe import Pipe

my_pipe = Pipe(
  name="my_pipe",
  comment="creating my pipe",
  copy_statement="COPY INTO my_table FROM @mystage FILE_FORMAT = (TYPE = 'JSON')",
)

pipes = root.databases["my_db"].schemas["my_schema"].pipes
pipes.create(my_pipe)
Copy

์ด ์ฝ”๋“œ๋Š” PipeCollection ๋ณ€์ˆ˜ pipes ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  PipeCollection.create ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์— ์ƒˆ ํŒŒ์ดํ”„๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„ ์„ธ๋ถ€ ์ •๋ณด ์–ป๊ธฐยถ

Pipe ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” PipeResource.fetch ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํŒŒ์ดํ”„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” my_pipe ํŒŒ์ดํ”„์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

my_pipe = root.databases["my_db"].schemas["my_schema"].pipes["my_pipe"].fetch()
print(my_pipe.to_dict())
Copy

ํŒŒ์ดํ”„ ๋‚˜์—ดํ•˜๊ธฐยถ

Pipe ์˜ค๋ธŒ์ ํŠธ์˜ PagedIter ๋ฐ˜๋ณต๊ธฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” PipeCollection.iter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ดํ”„๋ฅผ ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ์ด๋ฆ„์ด my ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํŒŒ์ดํ”„๋ฅผ ๋‚˜์—ดํ•˜๊ณ  ๊ฐ ๊ณ„์ •์˜ ์ด๋ฆ„์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

from snowflake.core.pipe import PipeCollection

pipes: PipeCollection = root.databases["my_db"].schemas["my_schema"].pipes
pipe_iter = pipes.iter(like="my%")  # returns a PagedIter[Pipe]
for pipe_obj in pipe_iter:
  print(pipe_obj.name)
Copy

ํŒŒ์ดํ”„ ์ž‘์—… ์ˆ˜ํ–‰ํ•˜๊ธฐยถ

ํŒŒ์ดํ”„ ์ƒˆ๋กœ ๊ณ ์นจ ๋ฐ ํŒŒ์ดํ”„ ์‚ญ์ œ์™€ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ํŒŒ์ดํ”„ ์ž‘์—…์„ PipeResource ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ 

ํ˜„์žฌ ALTER PIPE ์˜ REFRESH ๊ธฐ๋Šฅ๋งŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„ ๋ฆฌ์†Œ์Šค๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. my_pipe ํŒŒ์ดํ”„ ๋ฆฌ์†Œ์Šค ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

  2. ์ง€์ •๋œ ์„ ํƒ์  ์ ‘๋‘์‚ฌ(๋˜๋Š” ๊ฒฝ๋กœ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค€๋น„๋œ ๋ฐ์ดํ„ฐ ํŒŒ์ผ๋กœ ํŒŒ์ดํ”„๋ฅผ ์ƒˆ๋กœ ๊ณ ์นฉ๋‹ˆ๋‹ค.

  3. ํŒŒ์ดํ”„๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

my_pipe_res = root.databases["my_db"].schemas["my_schema"].pipes["my_pipe"]

# equivalent to: ALTER PIPE my_pipe REFRESH PREFIX = 'dir3/'
my_pipe_res.refresh(prefix="dir3/")

my_pipe_res.drop()
Copy

์™ธ๋ถ€ ๋ณผ๋ฅจ ๊ด€๋ฆฌยถ

์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” Snowflake๋ฅผ Apache Icebergโ„ข ํ…Œ์ด๋ธ”์˜ ์™ธ๋ถ€ ํด๋ผ์šฐ๋“œ ์ €์žฅ์†Œ์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฆ„์ด ์ง€์ •๋œ ๊ณ„์ • ์ˆ˜์ค€์˜ Snowflake ์˜ค๋ธŒ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ Apache Icebergโ„ข ํ…Œ์ด๋ธ” ์˜ ์™ธ๋ถ€ ๋ณผ๋ฅจ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Snowflake Python APIs ์€ ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

  • ExternalVolume: ์™ธ๋ถ€ ๋ณผ๋ฅจ์˜ ์ด๋ฆ„, ์ €์žฅ ์œ„์น˜ ๋“ฑ์˜ ์†์„ฑ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

  • ExternalVolumeResource: ํ•ด๋‹น ExternalVolume ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ์ œ๊ฑฐ ๋˜๋Š” ๋ณต์›ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

์™ธ๋ถ€ ๋ณผ๋ฅจ ๋งŒ๋“ค๊ธฐยถ

์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋จผ์ € ExternalVolume ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ API Root ์˜ค๋ธŒ์ ํŠธ์—์„œ ExternalVolumeCollection ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ExternalVolumeCollection.create ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Snowflake์— ์ƒˆ ์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ์ง€์ •๋œ AWS S3 ์ €์žฅ์†Œ๊ฐ€ ์žˆ๋Š” my_external_volume ์ด๋ผ๋Š” ์ด๋ฆ„์˜ ์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ๋‚˜ํƒ€๋‚ด๋Š” ExternalVolume ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

from snowflake.core.external_volume import (
    ExternalVolume,
    StorageLocationS3,
)

my_external_volume = ExternalVolume(
    name="my_external_volume",
    storage_locations=[
        StorageLocationS3(
            name="my-s3-us-west-1",
            storage_base_url="s3://MY_EXAMPLE_BUCKET/",
            storage_aws_role_arn="arn:aws:iam::123456789012:role/myrole",
            encryption=Encryption(type="AWS_SSE_KMS", kms_key_id="1234abcd-12ab-34cd-56ef-1234567890ab"),
        ),
        StorageLocationS3(
            name="my-s3-us-west-2",
            storage_base_url="s3://MY_EXAMPLE_BUCKET/",
            storage_aws_role_arn="arn:aws:iam::123456789012:role/myrole",
            encryption=Encryption(type="AWS_SSE_KMS", kms_key_id="1234abcd-12ab-34cd-56ef-1234567890ab"),
        ),
    ]
)

root.external_volumes.create(my_external_volume)
Copy

์™ธ๋ถ€ ๋ณผ๋ฅจ ์„ธ๋ถ€ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐยถ

ExternalVolume ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ExternalVolumeResource.fetch ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์™ธ๋ถ€ ๋ณผ๋ฅจ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” my_external_volume ์™ธ๋ถ€ ๋ณผ๋ฅจ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

my_external_volume = root.external_volumes["my_external_volume"].fetch()
print(my_external_volume.to_dict())
Copy

์™ธ๋ถ€ ๋ณผ๋ฅจ ๋‚˜์—ดยถ

ExternalVolume ์˜ค๋ธŒ์ ํŠธ์˜ PagedIter ๋ฐ˜๋ณต๊ธฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ExternalVolumeCollection.iter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ๋‚˜์—ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ์ด๋ฆ„์ด my ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ๋‚˜์—ดํ•˜๊ณ  ๊ฐ ๊ณ„์ •์˜ ์ด๋ฆ„์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

external_volume_iter = root.external_volumes.iter(like="my%")
for external_volume_obj in external_volume_iter:
  print(external_volume_obj.name)
Copy

์™ธ๋ถ€ ๋ณผ๋ฅจ ์ž‘์—… ์ˆ˜ํ–‰ยถ

์™ธ๋ถ€ ๋ณผ๋ฅจ ์ œ๊ฑฐ ๋ฐ ๋ณต์›๊ณผ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ์™ธ๋ถ€ ๋ณผ๋ฅจ ์ž‘์—…์„ ExternalVolumeResource ์˜ค๋ธŒ์ ํŠธ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์™ธ๋ถ€ ๋ณผ๋ฅจ ๋ฆฌ์†Œ์Šค๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. my_external_volume ์™ธ๋ถ€ ๋ณผ๋ฅจ ๋ฆฌ์†Œ์Šค ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

  2. ์™ธ๋ถ€ ๋ณผ๋ฅจ์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

  3. ์ œ๊ฑฐํ•œ ์™ธ๋ถ€ ๋ณผ๋ฅจ์˜ ๊ฐ€์žฅ ์ตœ๊ทผ ๋ฒ„์ „์„ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค.

my_external_volume_res = root.external_volumes["my_external_volume"]
my_external_volume_res.drop()
my_external_volume_res.undrop()
Copy