본문 바로가기
개발 공부/Django

F() Expression

by 느림보어른 2021. 8. 18.

서문

Django의 성능을 높이기 위한 여러 방안을 검색하면서 F() Expression에 대해 알게 되었다. 이 포스팅은 F() Expression에 대해 내가 공부한 내용들을 정리한 것이다.

F() Expression 이란?

django 공식문서에서 설명하는 F()는 다음과 같다.

F() 개체는 모델 필드의 값, 모델 필드의 변환 값 또는 주석이 달린 열을 나타냅니다. 이를 통해 실제 데이터베이스에서 Python 메모리로 가져올 필요 없이 모델 필드 값을 참조하고 이를 사용하여 데이터베이스 작업을 수행할 수 있습니다.

대신 Django는 F() 개체를 사용하여 데이터베이스 수준에서 필요한 작업을 설명하는 SQL 식을 생성합니다.

위의 설명에서 내가 주목한 것은 바로 Python 메모리이다. 이것이 F()를 사용할 때와 사용하지 않을 때 어떤 차이가 있는 지 알아보자

F()를 사용하지 않은 일반적인 경우

# Tintin filed a news story!
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed += 1
reporter.save()

여기서는 데이터베이스에서 reporter.stories_filed 값을 메모리로 가져와 익숙한 Python 연산자를 사용하여 조작한 다음 개체를 데이터베이스에 다시 저장했다. 즉, 메모리가 사용되었으며 python이 해당 작업을 전부 처리한다.

F()를 사용한 경우

from django.db.models import F

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()

Django가 F()의 인스턴스를 발견하면 표준 Python 연산자를 재정의하여 캡슐화된 SQL 식을 만든다. 위의 경우 reporter.stories_filed를 +1하도록 데이터베이스에 지시한다. 즉, 해당 과정은 python이 아닌 데이터베이스가 처리한다.

python이 하는 일은 필드를 참조하고 작업을 설명하는 SQL 구문을 만드는 것이다.

 

reporter = Reporters.objects.filter(name='Tintin')
reporter.update(stories_filed=F('stories_filed') + 1)

F()의 첫번째 예시에서는 get을 사용했지만 위의 예시에서는 filter와 update를 사용해 save()를 할 필요가 없게하여 쿼리 수를 줄일 수 있다.

F()의 장점

  • Python이 아닌 데이터베이스가 작동하도록 한다.
  • 일부 작업에 필요한 쿼리 수를 줄인다.
  • 경쟁 상태(race condition)를 방지할 수 있다.

경쟁 상태(race condition)

공학 분야에서 경쟁 상태(race condition)란 둘 이상의 입력 또는 조작의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태를 말한다. 입력 변화의 타이밍이나 순서가 예상과 다르게 작동하면 정상적인 결과가 나오지 않게 될 위험이 있는데 이를 경쟁 상태이라고 한다.

 

위의 F()가 없는 경우의 코드를 예를 들어, 두 명의 사용자가 접속했을 때 만약에 먼저 접속한 사용자가 save()하기 전에 후에 접속한 사용자가 데이터를 불러올 경우 해당 데이터는 먼저 접속한 사용자의 작업을 수정하지 못한 데이터이기에 결과적으로 먼저 접속한 사용자의 작업은 없던 작업이 되어버린다. 이러한 현상이 발생할 수 있는 상태가 경쟁 상태라고 한다.

 

하지만 F()를 사용하면 데이터베이스내에서 자그업이 이루어지기에 순서대로 작업이 처리되어 이러한 경쟁 상태가 발생되는 것을 방질할 수 있다.

참고

https://ko.wikipedia.org/wiki/%EA%B2%BD%EC%9F%81_%EC%83%81%ED%83%9C

 

경쟁 상태 - 위키백과, 우리 모두의 백과사전

논리 상태에서의 경쟁 상태 공학 분야에서 경쟁 상태(race condition)란 둘 이상의 입력 또는 조작의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태를 말한다. 입력 변화의 타이밍이나 순서

ko.wikipedia.org

https://docs.djangoproject.com/en/3.2/ref/models/expressions/#django.db.models.F

 

Query Expressions | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com