TIL91. Django ORM : Logging & Lazy Loading

10421 단어 ORMORM

📌 이 포스팅에서는 query를 logging하는 방법과 Lazy Loading에 대해 정리하였습니다.


🌈 Logging & Lazy Loading

🔥 Logging 다는 방법

🔥 Lazy Loading 이란?


1. Logging

🤔 Django Logging 다는 법

✔️ settgins.py에 logging을 달면, django가 실행되는 동안 발생되는 query의 양을 확인할 수 있다.

✔️ 즉, 내가 구현한 API가 DB에 어떤 요청을 발생시킬 때 마다 어떤 SQL문이 실행되는지 확인할 수 있고, shell에서도 작동한다.

✔️ 이를 통해 API의 성능을 테스트할 수 있고, 최적화에 대한 지표로 사용된다.

✔️ 아래 방법은 코드 실행때마다 쿼리가 찍히는 설정이다.

#settings.py
LOGGING = {
    'disable_existing_loggers': False,
    'version': 1,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

✔️ 아래 방법은 코드 실행때마다 찍힌 쿼리를 log 파일로 저장하는 방법이다. 이 방법을 쓸 때에는 .gitignore 로그 파일이 추적되지 않게 추가시켜야한다.

#settings.py
LOGGING = {
    'disable_existing_loggers': False,
    'version': 1,
    'formatters': {
         'verbose': {
            'format': '{asctime} {levelname} {message}',
            'style': '{'
        },
    },
    'handlers': {
        'console': {
            'class'     : 'logging.StreamHandler',
            'formatter' : 'verbose',
            'level'     : 'DEBUG',
        },
        'file': {
            'level'     : 'DEBUG',
            'class'     : 'logging.FileHandler',
            'formatter' : 'verbose',
            'filename'  : 'debug.log',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers' : ['console','file'],
            'level'    : 'DEBUG',
            'propagate': False,
        },
    },
}

2. Lazy Loading 이란?

🤔 Lazy Loading

✔️ Django뿐 아니라 다른 ORM에서도 Lazy-loading방식을 사용한다. Lazy Loading은 CS 전반의 개념으로 generator의 개념과 유사하다.

✔️ Lazy-loading이란 ORM에서 명령을 실행할 때마다 DB에 접근하여 데이터를 가져오는 것이 아닌 실제 데이터를 불러와야할 때 Query문을 실행하는 방식을 의미한다.

✔️ 즉, DB에 요청하는 로직을 매번 실행시켜 DB에 무리를 주는게 아닌, 최종적으로 Query문이 평가되어야할 때 DB에 요청하는 게으른 방식이다.

✔️ 실제로 호출(평가)하는 시점 : slicing, Iteration(for문), if문, print(), repr(), len(), list(), bool() 등

✔️ 이에 alll, filter, exclude, annotate문이 존재할 때는 바로 호출하지 않지만, print()문이 있을 때는 query를 실행시켜 DB에 요청한다.

✔️ 아래 코드는 query문이 4회 호출된다.

query = User.objects.filter(name_startswith = "kim")
queyry[0]     # 👈 1회 호출
queyry[1]     # 👈 2회 호출
queyry[2]     # 👈 3회 호출
list(queyry)  # 👈 4회 호출

✔️ 아래 코드는 query문이 1번 실행되기 때문에 DB에 1회 호출된다. list()를 할 때 query가 실행되는데 list()가 이미 리소스를 캐슁해두었기 때문에 그 아래 slicing에서는 캐슁한 리소스를 사용하고, 다시 DB를 호출하기 위해 query문을 실행시키지 않는다.

query = User.objects.filter(name_startswith = "kim")
list(queyry) # 👈 1회 호출
queyry[0]
queyry[1]
queyry[2]

좋은 웹페이지 즐겨찾기