FrontEnd
Javascript
Diary
ML
CS
Django
Algorithm
AWS
Co-Work
HTML
CSS
Python
React
ReactNative

Django Query & DBLayer

๐Ÿ“ฉ์ฟผ๋ฆฌ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ ˆ์ด์–ด

๋‹ค๋ฅธ ORM๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์žฅ๊ณ ๋Š” ์—ฌ๋Ÿฌ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ DB์ข…๋ฅ˜์™€๋Š” ๋…๋ฆฝ์ ์ธ ํ˜•ํƒœ๋กœ ๊ฐ์ฒดํ™” ๊ทธ๋ฆฌ๊ณ  ์ƒํ˜ธ์ž‘์šฉ๊ฐ€๋Šฅํ•œ ๋ฉ”์„œ๋“œ ์ œ๊ณต

  • ๋‹จ์ผ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ž‘์—…ํ•˜๋Š” detail๋ทฐ์—์„œ๋Š” get()๋Œ€์‹  get_object_or_404()๋ฅผ ์ด์šฉํ•˜์ž

๋‹จ! get_object_or_404()๋Š” ์˜ค์ง views์—์„œ๋งŒ ์ด์šฉํ•œ๋‹ค

  • ์˜ˆ์™ธ๋ฅผ ์ผ์œผํ‚ฌ์ˆ˜ ์žˆ๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ฃผ์˜ํ•ด์„œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์ž

Error์— ๋Œ€ํ•ด์„œ

ObjectDoesNotExist๋Š” ์–ด๋–ค ๋ชจ๋ธ๊ฐ์ฒด์—์„œ๋„ ์ด์šฉ๊ฐ€๋Šฅํ•˜์ง€๋งŒ DoesNotExist๋Š” ํŠน์ • ๋ชจ๋ธ์—์„œ์˜ ์กด์žฌ ์œ ๋ฌด์—์„œ๋งŒ ์ด์šฉ๊ฐ€๋Šฅ

์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค๋ฉด MultipleObjectsReturned

  • ์ฟผ๋ฆฌ๋ฅผ ์ข€๋” ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด ์ง€์—ฐ ์—ฐ์‚ฐ ์ด์šฉ

์žฅ๊ณ ์˜ ORM์€ ๊ฐ•๋ ฅํ•˜๊ธฐ์— ์ฝ”๋“œ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•ด์•ผํ•œ๋‹ค. ๋ณต์žกํ•œ ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ ๋ช‡์ค„ ์•ˆ๋˜๋Š” ์ฝ”๋“œ์— ๋„ˆ๋ฌด ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์šฐ๊ฒจ๋„ฃ์ง€ ๋ง์ž

์ง€์—ฐ ์—ฐ์‚ฐ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ •๋ง๋กœ ํ•„์š”ํ•˜๊ธฐ ์ „๊นŒ์ง€ ์žฅ๊ณ ๊ฐ€ SQL์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ํŠน์ง• ๋”ฐ๋ผ์„œ ORM๋ฉ”์„œ๋“œ์™€ ํ•จ์ˆ˜๋ฅผ ์›ํ•˜๋Š” ๋งŒํผ ์—ฐ๊ฒฐํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์งค์ˆ˜ ์žˆ๋Š”๋ฐ ๊ฒฐ๊ณผ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ์ „๊นŒ์ง€ DB์™€ ์—ฐ๋™๋˜์ง€ ์•Š๊ธฐ๋•Œ๋ฌธ์ด๋‹ค ๋”ฐ๋ผ์„œ ํ•œ์ค„์— ์šฐ๊ฒจ๋„ฃ๋˜๊ฒƒ์„ ์—ฌ๋Ÿฌ์ค„์— ์“ธ์ˆ˜์žˆ๋‹ค.

์ž๋™์œผ๋กœ ๋‚˜๋ˆ ์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ง€์—ฐ์—ฐ์‚ฐ ์ ์šฉ๋œ๋‹ค

  • ๊ณ ๊ธ‰์ฟผ๋ฆฌ๋„๊ตฌ ์ด์šฉํ•˜๊ธฐ

ORM์œผ๋กœ ์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์–ธ์–ด๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•˜๋Š”๊ฒƒ๋ณด๋‹ค DB๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š”๊ฒƒ์ด ๋” ๋น ๋ฅด๋ฏ€๋กœ ๊ณ ๊ธ‰ ์ฟผ๋ฆฌ๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด DB์™€ Django์‚ฌ์ด์— ์ง€์†์ ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค

๋งŒ์•ฝ Python์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด ๋Š๋ฆฌ๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋ชจ๋„ ๋งŽ์•„์ง€๋ฉฐ race condition์ด ๊ฑธ๋ ค ๊ณต์œ  ์ž์›์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ ‘๊ทผํ•ด ๋ฐ์ดํ„ฐ ๋ถ„์‹ค์ด ์ƒ๊ธธ์ˆ˜ ์žˆ๋‹ค.

์ฟผ๋ฆฌํ‘œํ˜„์‹์„ ๊ผญ ์ตํ˜€๋‘์ž ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์˜ ํ–ฅ์ƒ์„ ๊ฐ€์ ธ์˜ฌ๊ฒƒ์ด๋‹ค

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ•จ์ˆ˜ ์ด์šฉ

UPPER(), LOWER(), COALESCE(), CONCAT(), LENGTH(), SUBSTR()๋“ฑ์˜ ๋ฐ์ดํ„ฐํ•จ์ˆ˜๋ฅผ ์ด์šฉํ• ์ˆ˜์žˆ๋Š”๋ฐ

์ด์šฉ์ด ๋งค์šฐ์‰ฝ๊ณ  ๊ฐ„๊ฒฐํ•˜๋ฉฐ ์„ฑ๋Šฅํ–ฅ์ƒ์„ ๊ฐ€์ ธ์˜ฌ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ DB๋ณ„๋กœ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋“ค์„ ์žฅ๊ณ  ORM์ด ํ†ตํ•ฉํ•ด์ค˜ ๋‹ค๋ฅธ DB์˜ ์ฝ”๋“œ๋„ ์ž˜ ์ž‘๋™

  • ํ•„์ˆ˜ ๋ถˆ๊ฐ€๊ฒฐํ•œ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ผ๋ฉด rowSQL์€ ์ง€์–‘ํ•˜์ž

๋ณด์•ˆ, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋“ฑ ์—ฌ๋Ÿฌ ์ด์ ์ด ์žˆ์œผ๋‹ˆ ORM์„ ์ด์šฉํ•˜์ž ์•ฑ์ด ์„œ๋“œํŒŒํ‹ฐ ํŒจํ‚ค์ง€๋กœ ๋ฆด๋ฆฌ์Šค ๋ ๋•Œ์—๋„ ๋กœ์šฐ SQL์€ ์ด์‹์„ฑ์ด ๋–จ์–ด์ง„๋‹ค

๋กœ์šฐ SQL์€ ์‚ฌ์šฉํ• ๋•Œ ์ฝ”๋“œ๊ฐ€ ์›”๋“ฑํžˆ ๊ฐ„๊ฒฐํ•ด์ง€๊ณ  ๋‹จ์ถ•๋˜๋Š” ๊ฒฝ์šฐ์—๋งŒ (ex : ํฐ ๋ฐ์ดํ„ฐ ์…‹์— ์ ์šฉ๋˜๋Š” ๋‹ค์ˆ˜์˜ ์ฟผ๋ฆฌ์…‹ ์—ฐ๋™)

  • ํ•„์š”์—๋”ฐ๋ผ ์ธ๋ฑ์Šค๋ฅผ ์ด์šฉํ•˜์ž

db_index = True๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋˜๋Š”๋ฐ

์ธ๋ฑ์Šค๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ด์šฉ๋ ๋•Œ (๋ชจ๋“  ์ฟผ๋ฆฌ์˜ 10~25% ์‚ฌ์ด) ์‹ค์ œ ๋ฐ์ดํ„ฐ๋˜๋Š” ๋น„์Šทํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•ด์„œ ์ธ๋ฑ์‹ฑ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ๋ถ„์„์ด ๊ฐ€๋Šฅํ• ๋•Œ ์ธ๋ฑ์‹ฑ์„ ํ†ตํ•ด ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜๋Š”์ง€ ํ…Œ์ŠคํŠธ ํ• ์ˆ˜ ์žˆ์„๋•Œ

==> ์ธ๋ฑ์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜์ž

  • ํŠธ๋žœ์žญ์…˜

ORM์ด ์ฟผ๋ฆฌ๋ฅผ ํ˜ธ์ถœํ• ๋•Œ ์ž๋™ ์ปค๋ฐ‹์„ ํ•ด์ฃผ๋Š”๊ฒƒ์œผ๋กœ ์ธํ•ด ์ฒ˜๋ฆฌ๊ณผ์ •์—์„œ ๋‘˜ ์ด์ƒ์˜ DB์˜ ์ˆ˜์ •์ด ์š”๊ตฌ๋˜๋ฉด ๋‘๋ฒˆ์จฐ ์ˆ˜์ •์—์„œ DB์ƒ์˜ ์ถฉ๋Œ์ด ์ผ์–ด๋‚ ์ˆ˜์žˆ๋Š”๋ฐ ํŠธ๋žœ์žญ์…˜์„ ์ด์šฉํ•˜๋ฉด ํ•ด๊ฒฐํ• ์ˆ˜ ์žˆ๋‹ค

DBํŠธ๋žœ์žญ์…˜์ด๋ž€ ๋‘˜ ๋˜๋Š” ์ด์ƒ์˜ DB UPDATE๋ฅผ ๋‹จ์ผํ™”๋œ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋ฒ• ์ฆ‰ ํ•˜๋‚˜์˜ ์ˆ˜์ •์ž‘์—…์ด ์‹คํŒจํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์ƒ์˜ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๊ฐ€ ์‹คํŒจ

์ด๋ฅผ ์ œ๋Œ€๋กœ ์ด์šฉํ•˜๊ธฐ์œ„ํ•ด์„œ๋Š” DB๊ฐ€ ACID(Atomic, Consistent, Isolated, Durable)์„ ๊ฐ€์ ธ์•ผํ•œ๋‹ค

HTTP์š”์ฒญ์„ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ž

#settings/base.py
DATABASES = {
'ATOMIC_REQUESTS' : True,
}

์œ„์ฒ˜๋Ÿผ ์„ค์ •์„ ํ•ด์ฃผ๊ฒŒ ๋˜๋ฉด ๋ชจ๋“  ์›น ์š”์ฒญ์„ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•ด์ค„์ˆ˜ ์žˆ๋‹ค.

์œ„์˜ ์„ค์ •์€ ๋ชจ๋“  DB์ฟผ๋ฆฌ๊ฐ€ ๋ณดํ˜ธ๋˜๋Š” ์•ˆ์ •์„ฑ์„ ์–ป์„์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ฉด DB์˜ ๋””์ž์ธ ์ž ๊ธˆ์ฒ˜๋ฆฌ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์„ฑ๋Šฅ์ €ํ•˜๋ฅผ ๋ณด์—ฌ์ค„์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ์„ค์ •์€ DB์˜ ๋ฌด๊ฒฐ์„ฑ์„ ์œ ์ง€ํ•˜๋Š”๋ฐ ํšจ๊ณผ์ ์ด์ง€๋งŒ ํŠธ๋ž˜ํ”ฝ์ด ๋งŽ์•„์ง€๋ฉด ๋ณ„๋กœ๋‹ค

๋˜ํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๋‚˜์„œ ๋กค๋ฐฑ๋˜๋ฏ€๋กœ ์ฒ˜๋ฆฌ๋œ ์ž‘์—…์— ๋Œ€ํ•œ ๋ฉ”์ผ ๋ฐœ์†ก ๋“ฑ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š”(DB๊ฐ€ ์•„๋‹Œ item์— ๋Œ€ํ•ด create update deleteํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š”) ๋ทฐ๋ฅผ transaction.nonatomicrequests()๋กœ ํ•ด์ฃผ์ž ํ•˜์ง€๋งŒ ์„ฑ๋Šฅ๋ฌธ์ œ๊ฐ€ ์ •๋ง ์‹ฌ๊ฐํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ATOMIC_REQUESTS ๋ฅผ ์ด์šฉํ•˜์ž

  • ๋ช…์‹œ์  ํŠธ๋žœ์žญ์…˜ ์„ ์–ธ

ํŠธ๋žœ์žญ์…˜์—์„œ ์–ด๋–ค ๋ทฐ, ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์ด ์–ฝํ˜€์žˆ๋Š”์ง€ ๋ช…์‹œํ•ด์ฃผ๋Š” ๊ฒƒ์œผ๋กœ ๋งŽ์€ ๊ฐœ๋ฐœ์‹œ๊ฐ„์„ ์š”ํ•œ๋‹ค.

๊ฐ€์ด๋“œ๋ผ์ธ

  • DB์— ๋ณ€๊ฒฝ์ด ์ƒ๊ธฐ์ง€ ์•Š๋Š” DB์ž‘์—…์€ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ฒ˜๋ฆฌ X
  • DB์— ๋ณ€๊ฒฝ์ด ์ƒ๊ธฐ๋Š” ๊ฒƒ์€ ๋ฐ˜๋“œ์‹œ ํŠธ๋žœ์žญ์…˜์ฒ˜๋ฆฌ
  • DB ์ฝ๊ธฐ๋ฅผ ํ•˜๋Š” DB๋ณ€๊ฒฝ์ž‘์—… ๋˜๋Š” ์„ฑ๋Šฅ๊ด€๋ จ ๊ฒฝ์šฐ์—๋Š” ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ์™€ ๋น„์ฒ˜๋ฆฌ๋ฅผ ๋‘˜๋‹ค ๊ณ ๋ ค

ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌํ•˜๋Š” ORM
์ƒ์„ฑ : .create(), .bulkcreate(), .getor_create()
์ˆ˜์ • : .update()
์‚ญ์ œ : .delete()

ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ X ORM
๊ฐ€์ ธ์˜ค๊ธฐ : .get(), .filter(), .count(), .iterate(), .exists(), .exclude(), .in_bulk() ๋“ฑ

๋‹จ ๋…๋ฆฝ์ ์ธ ORM ์€ ์ž์ฒด์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ธฐ๋•Œ๋ฌธ์—
์—ฌ๋Ÿฌ ORM๋“ค์„ ๋ทฐ๋‚˜ ํ•จ์ˆ˜ or ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœํ• ๋•Œ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์ž