[FastAPI] 13. SQLAlchemy์™€ Pydantic์„ ์ด์šฉํ•œ ๊ด€๊ณ„ ๋ฐ์ดํ„ฐ ๋งคํ•‘

๋ฐ˜์‘ํ˜•

SQLAlchemy๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋ฉด ์›ํ•˜์ง€ ์•Š์„ ๋•Œ API์—์„œ ๋ชจ๋“  ์ปฌ๋Ÿผ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€ ์ตœ์ ํ™” ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์šธ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค API์—์„œ๋Š” ํŠน์ • ์ปฌ๋Ÿผ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ํ˜น์€ ๊ด€๊ณ„ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•  ๋•Œ๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ๋ ‡์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋ชจ๋‘ ๋‚˜์˜ค๊ฒŒ ๋˜์–ด ์˜คํžˆ๋ ค API ๋กœ๋”ฉ ์†๋„๋ฅผ ์ €ํ•˜์‹œํ‚ค๊ณ  ์„œ๋ฒ„ ๋ถ€ํ•˜์— ์›์ธ์ด ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

SQLAlchemy ORM์˜ relationship

SQLAlchemy ORM์—์„œ๋Š” ๊ด€๊ณ„๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด relationship์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ธ”๋กœ๊ทธ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“œ๋ ค๋Š”๋ฐ, ์–ด๋–ค ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ธ€์ธ์ง€๋ฅผ ์•Œ๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ๋ฅผ ์„ค๊ณ„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์นดํ…Œ๊ณ ๋ฆฌ๋Š” ํ•˜์œ„ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ , ํ•˜๋‚˜์˜ ์ปจํ…์ธ ๋Š” ์นดํ…Œ๊ณ ๋ฆฌ ํ•˜๋‚˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค๋ผ๊ณ  ํ–ˆ์„ ๋•Œ ์œ„์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค๊ณ„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์œ„ ์„ค๊ณ„๋Š” ๋ฐ˜๋“œ์‹œ ์ •๋‹ต์ด ๋  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.)

 

์œ„ ์ƒํ™ฉ์—์„œ SQLAlchemy ORM์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ง ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ ํ˜•ํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

 

๋ธ”๋กœ๊ทธ ์ปจํ…์ธ ๋ฅผ ์กฐํšŒํ–ˆ์„ ๋•Œ ์–ด๋–ค ์นดํ…Œ๊ณ ๋ฆฌ์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด relationship์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ๋œ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ CategoryEntity๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

 

 

Pydantic with relationship

FastAPI์—์„œ response๋กœ ์‘๋‹ตํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”? ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ฒŒ๋Š” ORM ๋ชจ๋ธ์„ JsonDecoder ๋“ฑ์„ ์ด์šฉํ•˜์—ฌ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ DateTime์ด๋‚˜ ์ง€๊ธˆ์ฒ˜๋Ÿผ relationship์„ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋ชจ๋ธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํƒ€์ž…์— ๋Œ€ํ•ด JSON ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๋กœ์ง์„ ์ผ์ผ์ด ์ˆ˜ํ–‰ํ•ด์ค˜์•ผ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋ฅผ ์ข€ ๋” ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Pydantic์— ๋‚ด์žฅ๋œ ORM Mode์™€ FastAPI์˜ jsonable_encoder๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ JSON ํŒŒ์„œ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ Pydantic ๋ชจ๋ธ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๊ณ  ์ด์— ๋งž์ถฐ JSON ํฌ๋งท์œผ๋กœ ์ธ์ฝ”๋”ฉ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๊ฐ€์ง€ ํŽธ๋ฆฌํ•œ ์ด์ ์„ ์–ป์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Pydantic์—์„œ BaseModel์€ Python์˜ dict ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ Pydantic ๋ชจ๋ธ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋ฉฐ ์—ฌ๊ธฐ์— orm_mode๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ SQLAlchemy์˜ ORM Model ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ Pydantic ๋ชจ๋ธ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋กœ์ง์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ด๋ฅผ API๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ ๊ตฌ์ฒด์ ์ธ ์ฝ”๋“œ๋Š” ์ ์ง€ ์•Š๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ์–ด๋–ค ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋”ฐ๋ผ ์—ฌ๋ถ€๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ค‘์š”ํ•œ ์ ์€ response_model์— ์œ„์—์„œ ์ •์˜ํ•œ Pydantic ๋ชจ๋ธ์„ ์ •์˜ํ•˜๋ฉด ๋˜๊ณ  api์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ORM ๋ชจ๋ธ๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ, ์–ด๋–ป๊ฒŒ API์—์„œ ORM ๋ชจ๋ธ๋งŒ ๋ฐ˜ํ™˜ํ–ˆ๋Š”๋ฐ, ๋ฐ”๋กœ Pydantic ๋ชจ๋ธ์ด ๋˜์–ด JSON์œผ๋กœ ๋‚˜์˜ฌ ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ผ๊นŒ์š”?

 

 

 

FastAPI jsonable_encoder

FastAPI์—์„œ๋Š” ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜์‹œ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ์ธ์ฝ”๋”๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธ์ฝ”๋”๋Š” ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” json์˜ dumps์™€ ๊ฐ™์€ ๋กœ์ง์ด ์•„๋‹™๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์›ํ•œ๋‹ค๋ฉด ujson์„ ์“ธ ์ˆ˜๋„ ์žˆ๊ณ  orjson์„ ์“ธ ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์ด์— ๋งž์ถฐ์„œ ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ์ธ์ฝ”๋”ฉํ•ด์ฃผ๋Š” ์•„์ฃผ ์ข‹์€ ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค.

 

์‹ค์ œ๋กœ FastAPI๋Š” ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋กœ Pydantic์„ ์ฑ„ํƒํ•˜๊ณ  ์žˆ์œผ๋ฉฐ response_model์— Pydantic ๋ชจ๋ธ์„ ๋ช…์‹œํ•˜๋Š” ๊ฒฝ์šฐ jsonable_encoder ํ•จ์ˆ˜๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ jsonable_encoder๋Š” ์˜ค์ง dict ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋งŒ์„ json ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š”๋ฐ, orm_mode๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ Pydantic์˜ from_orm์ด๋ผ๋Š” ํ•จ์ˆ˜์— ์žˆ๋Š” ๋กœ์ง ๊ทธ๋Œ€๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ json ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์œ„ ์‚ฌ์ง„์€ ์‹ค์ œ๋กœ FastAPI๊ฐ€ response_model์„ ์ •์˜ํ•˜์˜€์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. Pydantic ๋ชจ๋ธ์„ ์ •์˜ํ•˜์˜€์„ ๋•Œ๋Š” ๋ฐ”๋กœ dict๋กœ ๋ณ€ํ™˜ํ•ด์„œ json์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ณ , orm_mode๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” from_orm ํ•จ์ˆ˜์— ์˜์กดํ•œ ์ฑ„ ๋ฐ”๋กœ json์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ from_orm์€ FastAPI์—์„œ ์ œ๊ณตํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ Pydantic BaseModel์—์„œ ์ œ๊ณตํ•˜๋Š” classmethod๋กœ์จ FastAPI๋Š” dict๋กœ ๋ณ€ํ™˜ ์—†์ด ์ด ๋ฐ์ดํ„ฐ๋งŒ์„ ์ด์šฉํ•ด json์œผ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด SQLALchemy ๋ชจ๋ธ์—์„œ ์ˆ˜๋™์œผ๋กœ dict๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ด์ฌ ๊ฐ์ฒด ๋ฉ”์„œ๋“œ์˜ __dict_-์™€ __fieds_set__์„ ๋ณด๊ณ  ๊ฐ’์„ validation ํ•˜์—ฌ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

๋งˆ์น˜๋ฉฐ...

relationship์„ ์ด์šฉํ•˜์—ฌ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ค์‹์œผ๋กœ json ๊ฐ’์— ๋„ฃ์–ด ๋ณด๋‚ด๋Š”์ง€๋ฅผ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํžˆ ์“ฐ๊ธฐ์—๋Š” ์–ด๋ ค์›Œ ๋ณด์ด์ง€ ์•Š์ง€๋งŒ ManyToOne, ManyToMany ๋“ฑ ๋‹ค์–‘ํ•œ ๊ด€๊ณ„์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ์—๋Š” ์•„์ง ๋‹ค์†Œ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค์Œ ํฌ์ŠคํŠธ์—์„œ ๋‹ค๋ค„๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” FastAPI์—์„œ ์–ด๋–ค ์‹์œผ๋กœ relationship์„ ๋‹ค๋ฃจ๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์„ ๋ชฉ์ ์œผ๋กœ ํ•˜์˜€์œผ๋ฉฐ ์šฐ๋ฆฌ๋Š” ์ด ๋ฐฉ์‹์ด ์–ด๋–ค ๋ฐฉ์‹์ธ์ง€๋ฅผ ์ด์ œ ์•Œ์•˜์œผ๋‹ˆ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์˜ relationship ์‚ฌ์šฉ๋ฒ•์„ ์•Œ์•„๋ณด๋ฉด์„œ ์ฟผ๋ฆฌ๋ฅผ ์ตœ์ ํ™” ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments