[FastAPI] 9. Persistence Layer ๊ตฌ๊ฐ„์„ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐ˜์‘ํ˜•

์ฒซ ํฌ์ŠคํŠธ์—์„œ ์šฐ๋ฆฌ๋Š” FastAPI๊ฐ€ ASGI ๊ธฐ๋ฐ˜์˜ uvicorn์„ ์ด์šฉํ•˜์—ฌ uvloop์— ๊ธฐ๋ฐ˜ํ•œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋กœ API ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋ฅผ ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ณต๊ต๋กญ๊ฒŒ๋„ Database Connection์—์„œ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ด์ฃผ์ง€ ์•Š์•„ API ์š”์ฒญ ๋‹จ์—๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜์—ฌ๋„ DB์— ์•ก์„ธ์Šค ํ•˜๋Š” ๊ตฌ๊ฐ„์€ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Blocking์ด ๋ฐœ์ƒํ•˜๊ณ , ๋‹ค์Œ ์š”์ฒญ์ด ๊ณ„์† ๋Œ€๊ธฐ ๋˜๋Š” ๋ฌธ์ œ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

Python DB API

๊ทธ๋ ‡๋‹ค๋ฉด ํŒŒ์ด์ฌ์€ ์–ด๋–ค์‹์œผ๋กœ Database์™€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ผ๊นŒ์š”? Java์˜ ๊ฒฝ์šฐ๋Š” JDBC๋ผ๋Š” Database Connector๋ผ๋Š” ๊ฒƒ์ด ์กด์žฌํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ Database ์‚ฌ์ด๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•œ๋ฐ์š”.

 

Python์—๋Š” ์ด์™€ ๋น„์Šทํ•œ ๊ฒƒ์œผ๋กœ DB API๋ผ๋Š” ๊ฒƒ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. 

 

 

PEP 249 -- Python Database API Specification v2.0

The official home of the Python Programming Language

www.python.org

ํŒŒ์ด์ฌ ๋ฌธ์„œ PEP 249์—๋Š” Python DB API 2.0์ด ๋‹ด๊ฒจ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ด์ฌ์—์„œ DB์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์šฐ๋ฆฌ๊ฐ€ ์ด์ „์— ๋‹ค๋ค˜๋˜ FastAPI CRUD ๋งŒ๋“ค๊ธฐ์—์„œ๋„ ์ด๋Ÿฌํ•œ ํ‘œ์ค€ API ๊ธฐ๋ฐ˜์˜ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์•ก์„ธ์Šค ํ–ˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์ข€ ๋” ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๊ทธ๋ฆผ์œผ๋กœ ๋ณด์—ฌ๋“œ๋ฆฌ์ž๋ฉด, asyncpg๋ผ๋Š” PostgreSQL์„ ์œ„ํ•œ DB ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” Python DB API๋ฅผ ๊ธฐ๋ณธ ๊ณจ๊ฒฉ์œผ๋กœ ํ•˜์—ฌ PostgreSQL์— ๋งž์ถฐ์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฉฐ ์ปค๋„ฅ์…˜์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด Connection ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , Query๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด Cursor ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ , connection ์œ„์— execute ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ Query๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋Š” asyncpg ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Python์—์„œ ์ง€์›ํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ DB ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„์ด ๋˜์–ด์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ํ‘œ์ค€ Python DB API ์ž…๋‹ˆ๋‹ค. 

 

 

 

 

(Old) Databases + asyncpg + SQLAlchemy 1.3

asyncpg๋Š” PosgreSQL์šฉ ๋น„๋™๊ธฐ DB ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ FastAPI์—์„œ๋Š” Databases์™€ asyncpg ๋ชจ๋“ˆ์„ ์กฐํ•ฉํ•˜์—ฌ SQLAlchemy Core์— ๊ธฐ๋ฐ˜ํ•œ ๋ฌธ๋ฒ•์„ ํ†ตํ•ด ๋น„๋™๊ธฐ ํŠธ๋žœ์žญ์…˜์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

asyncpg๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Python์˜ asyncio๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋ฉฐ Python 3.5 ๋ฒ„์ „๋ถ€ํ„ฐ ๋™์ž‘ํ•˜๊ณ , PostgreSQL 9.2 ~ 12 ๋ฒ„์ „๊นŒ์ง€๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

$ poetry add databases[asyncpg]

Databases ๋””ํŽœ๋˜์‹œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํŒจํ‚ค์ง€ ์ข…๋ฅ˜์— ์ž์‹ ์ด ์‚ฌ์šฉํ•  Database ์ด๋ฆ„์„ ๋„ฃ๊ณ  ๋””ํŽœ๋˜์‹œ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋””ํŽœ๋˜์‹œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋ฉด SQLAlchemy 1.3 ๋ฒ„์ „์˜ ๋””ํŽœ๋˜์‹œ๊ฐ€ ๊ฐ™์ด ์ถ”๊ฐ€๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๊ณต์‹์ ์œผ๋กœ SQLAlchemy์˜ 1.3 ๋ฒ„์ „์—์„œ๋Š” asyncpg dialect๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ FastAPI๋‚˜ Sanic ๊ฐ™์€ ๋น„๋™๊ธฐ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ Persistence Layer์— ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ๋„ฃ๊ธฐ ์œ„ํ•ด์„œ๋Š” asyncpgsa๋‚˜ ์šฐ๋ฆฌ๊ฐ€ ํ˜„์žฌ ๋‹ค๋ฃจ๊ณ  ์žˆ๋Š” databases์™€ ๊ฐ™์€ ํƒ€์‚ฌ์˜ ์–ด๋Œ‘ํ„ฐ์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

Databases ์–ด๋Œ‘ํ„ฐ์— ์—ฐ๊ฒฐํ•˜๊ณ ์ž ํ•˜๋Š” Database์˜ URI๋ฅผ ๋„ฃ๊ณ , ๋”๋ถˆ์–ด SQLAlchemy์˜ create_engine์—๋„ ๊ฐ™์ด URI๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ 2๊ฐ€์ง€ ์ „๋ถ€์— URI๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ์ด์œ ๋Š” Databases ์–ด๋Œ‘ํ„ฐ์—์„œ ์‹ค์ œ ํŠธ๋žœ์žญ์…˜์„ ๋งก๊ณ , SQLAlchemy์˜ Core๋ฅผ ์ด์šฉํ•˜์—ฌ Query๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

SQLAlchemy์—์„œ DB ์„œ๋ฒ„์— ์ ‘์†ํ•˜์—ฌ ํ•˜๋Š” ์ผ์€ ํ…Œ์ด๋ธ”์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ž€ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ DDL ์ •์˜๋ฅผ ์ด์•ผ๊ธฐ ํ•˜๋ฉฐ ์ฐจํ›„ ์ •์˜ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ DB ์„œ๋ฒ„์— ๋ณด๋‚ด์–ด DDL์„ ์ˆ˜ํ–‰ํ•ด ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• ์„ ํ•ด์ค๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์— QueryDSL๋ฐฉ์‹์˜ SQLAlchemy Core๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DB ์ฟผ๋ฆฌ๋ฅผ ์งˆ์˜ํ•˜๊ณ , ์ด ์ฟผ๋ฆฌ๋ฅผ Databases ๋ชจ๋“ˆ์˜ fetch_all์ด๋‚˜ execute ์™€ ๊ฐ™์€ Python DB API ํ•จ์ˆ˜์— ๋„ฃ์–ด์ฃผ๋ฉด ํŠธ๋žœ์žญ์…˜์ด ๋™์ž‘ํ•˜๋ฉฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฐ›์•„์น˜๋Š” ํ˜•์‹์ž…๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ๋ณต์žกํ•œ ํ”„๋กœ์‹œ์ €๋ฅผ ๊ฑฐ์น˜๋Š” ์ด์œ ๋Š” SQLAlchemy๊ฐ€ ์ž์ฒด์ ์œผ๋กœ asyncpg๋‚˜ aiopg์™€ ๊ฐ™์€ ๋น„๋™๊ธฐ ํŠธ๋žœ์žญ์…˜ ๋ชจ๋“ˆ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ ์— ์žˆ๊ณ , ์ด๋ฅผ ์ง€์›ํ•ด์ฃผ๋Š” ๋ณ„๋„์˜ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ธ๋ฐ, ๋งŒ์•ฝ ์ž์‹ ์ด ์ˆ˜๋™์œผ๋กœ Query๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” SQLAlchemy Core ์—†์ด๋„ Databases ๋ชจ๋“ˆ๋กœ๋งŒ์œผ๋กœ๋„ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ถฉ๋ถ„ํžˆ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

(New) SQLAlchemy 1.4.x + asyncpg

์ง€๋‚œ 3์›” 29์ผ๋ถ€ํ„ฐ SQLAlchemy 1.4.x ๋ฒ„์ „์ด ์ •์‹ ๋ฒ„์ „์œผ๋กœ ์ถœ์‹œ๋˜๋ฉด์„œ asyncpg๋ฅผ ์ด์ œ SQLAlchemy์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„์˜ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ณ„๋„์˜ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ SQLAlchemy์™€ Connection Pool๋งŒ ์žˆ๋‹ค๋ฉด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด์ฃ .

 

SQLAlchemy์—์„œ asyncpg๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ asyncpg ๋‚ด ํ•จ์ˆ˜๋‚˜ ๊ฐ์ฒด๋ฅผ ์„ ์–ธํ•  ํ•„์š” ์—†์ด ๋ฐ”๋กœ SQLALchemy์˜ create_async_engine ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปค๋„ฅ์…˜์„ ๋งŒ๋“ค๊ณ , DB ์ฒ˜๋ฆฌ ํ•จ์ˆ˜ ๋˜ํ•œ Alchemy์—์„œ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ธฐ์กด์ด๋ž‘ ๋‹ค๋ฅธ์ ์€ create_engine์ด ์•„๋‹Œ create_async_engine์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์ด๊ณ , PostgreSQL์„ ์‚ฌ์šฉํ•˜์‹ ๋‹ค๋ฉด ์—ฐ๊ฒฐ ํ˜•์‹์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด postgresql ๋’ค์— + asyncpg๋ฅผ ๋ถ™์ธ๋‹ค๋Š” ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ Session ๋˜ํ•œ AsyncSession์ด ๋ณ„๋„๋กœ ์กด์žฌํ•˜์—ฌ ORM์„ ์ด์šฉํ•œ DB ์ฒ˜๋ฆฌ์‹œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ์ธต ๊ฐ•ํ™”์‹œํ‚จ ์ ์ด ๋ˆˆ์— ๋ณด์ž…๋‹ˆ๋‹ค.

 

ORM์œผ๋กœ ์ •์˜ํ•œ ํด๋ž˜์Šค๋ฅผ DDL ์ฒ˜๋ฆฌํ•  ๋•Œ์—๋Š” ๋™๊ธฐ ์ฒ˜๋ฆฌ๋กœ ์ง„ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ ์ด ๋ˆˆ์— ๋ณด์ด๋Š”๋ฐ์š”. ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” create_all ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™๊ธฐ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— asyncio์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ run_sync ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ asyncio์™€ ํ˜ธํ™˜๋˜๋Š” ๋™๊ธฐ ๋ชจ๋ธ๋กœ ์‹คํ–‰ํ•˜๋„๋ก ์œ ๋„ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

DB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•๋„ ์กฐ๊ธˆ์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ธฐ์กด์—๋Š” sqlalchemy ์ƒ์œ„์— ์žˆ๋Š” select ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์ฟผ๋ฆฌ๋ฅผ ์งˆ์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‚˜ ORM session์—์„œ query ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ์ฟผ๋ฆฌ๋ฅผ ์งˆ์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋“ค ๋ชจ๋‘ ๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ด ๋ฐฉ๋ฒ•์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

 

SQLAlchemy 1.4 ๋ฒ„์ „์—์„œ ์ƒˆ๋กœ์ด ์ถ”๊ฐ€๋œ sqlalchemy.ext.asyncio.select ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ select ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜๊ณ , ์ด๋ฅผ ์ด์šฉํ•ด ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑ์ด ๋๋‚ฌ์œผ๋ฉด AsyncSession์˜ execute ๋น„๋™๊ธฐ ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฟผ๋ฆฌ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•˜๋ฉด ๊น”๋”ํ•˜๊ฒŒ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

 

์ด ๋‹ค์Œ ์‚ฌ์šฉํ•œ scalars์˜ ๊ฒฝ์šฐ๋Š” ๋ชจ๋ธ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๊ฑท๊ณ  ์ˆœ์ˆ˜ ๋ฐ์ดํ„ฐ๋งŒ์„ ๊ฐ€์ ธ์˜ค๊ฒ ๋‹ค๋Š” ํ•จ์ˆ˜์ด๋ฉฐ, fetchall์„ ํ†ตํ•ด ๊ฐ€์ ธ์˜ค๋ฉด ๊ธฐ์กด์— ์‚ฌ์šฉํ–ˆ๋˜ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฆฌํŒฉํ† ๋ง ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ˜น์‹œ SQLAlchemy์—์„œ select, where ๋“ฑ์˜ ๋น„ORM ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜์‹  ๋ถ„๋“ค์ด๋ผ๋ฉด session.refresh ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์…จ๊ฒ ์ง€๋งŒ ORM ํ•จ์ˆ˜์—์„œ๋Š” refresh ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์‹ค์ƒ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋ฅด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

SQLAlchemy 1.4์—์„œ๋Š” ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ์˜ ์ƒ์„ฑ์ด๋‚˜, ์—…๋ฐ์ดํŠธ ๋ฐœ์ƒ์‹œ ๋ชจ๋ธ ๊ฒฐ๊ณผ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์ฃผ๊ธฐ ์œ„ํ•ด refresh ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. AsyncSession์ด ๊ธฐ๋ณธ์ ์œผ๋กœ Session์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ AsyncEngine์„ ๋ถ™์ธ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์‹ค์ƒ Session ๊ฐ์ฒด๋ž‘ ๊ฑฐ์˜ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. 

 

๊ทธ๋Ÿฐ๋ฐ, commit ๋“ฑ๊ณผ ๊ฐ™์ด transaction์˜ ํ•จ์ˆ˜๋“ค์€ AsyncSession์—์„œ greenlet_spawn ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜๋„๋ก ์žฌ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€๋งŒ add, expire ๋“ฑ์˜ ํ•จ์ˆ˜๋“ค์€ ์žฌ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š์•„, ์‚ฌ์‹ค์ƒ AsyncSession์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” Session ํด๋ž˜์Šค๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

 

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

 

 

 

 

 

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

DB ๊ตฌ๊ฐ„์„ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ asyncpg ์™ธ์—๋„ aiopg๋ผ๋Š” ๋‹ค๋ฅธ ๋ชจ๋“ˆ๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋ณธ์ธ์ด ๊ฐœ๋ฐœํ•˜์‹œ๋Š” ํ”„๋กœ์ ํŠธ์—์„œ ์–ด๋–ค ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ณ  ๊ทธ์— ๋Œ€ํ•œ ์„ฑ๋Šฅ์„ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ์ด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ตฌํ˜„์„ ์ง„ํ–‰ํ•˜๋Š” ๋ฐ ์„  ์ž‘์—…์ด ๋˜์–ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

SQLAlchemy 1.4 ๋ฒ„์ „์„ ์‹œ์ž‘์œผ๋กœ ์•ž์œผ๋กœ๋Š” JPQL ๋ฐฉ์‹์ด ์•„๋‹Œ 2.x์˜ QueryDSL ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๋€” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํŒŒ์ด์ฌ์„ ๊ณ„์† ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ๋กœ ์ด์–ด๋‚˜๊ฐˆ ๋ถ„์ด์‹œ๋ผ๋ฉด ORM์„ SQLAlchemy๋กœ ์‚ฌ์šฉํ•˜์‹ค ๋•Œ ์ด ๋ถ€๋ถ„์„ ์—ผ๋‘ํ•ด๋‘๋Š” ๊ฒƒ์ด ์ข‹์•„ ๋ณด์ž…๋‹ˆ๋‹ค.

 

๋น„๋ก ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” asyncpg๋ผ๋Š” PostgreSQL์„ ์ฃผ์ œ๋กœ ๋‹ค๋ฃจ์—ˆ์ง€๋งŒ ํŒŒ์ด์ฌ DB API์—์„œ ๋น„๋™๊ธฐ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ชจ๋“ˆ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

  • MySQL (aiomysql)
  • PostgreSQL (aiopg, asyncpg)
  • SQLite (aiosqlite)

ํ•œ Dialect๋ฅผ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ง€์›ํ•˜๋Š” ๋ชจ๋“ˆ์—๋Š” ์œ„์˜ 3๊ฐ€์ง€๊ฐ€ ์žˆ์ง€๋งŒ MSSQL๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ Dialect์—์„œ๋„ aioodbc๋ฅผ ์ด์šฉํ•˜์—ฌ ODBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋กœ๋“œํ•œ ๋‹ค์Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments