1 minute read

1. 프롤로그

ORM이란 프로그래밍언어상의 객체와 관계형 데이터베이스 간의 매핑을 의미한다. RDBMS를 연동할 때, SQL이나 Stored Procedure를 사용할수 있지만 ORM을 사용하면, 좀더 효율적으로 개발이 가능하다.

ORM에선 SQL문을 사용하지 않기 때문에 추상화되어 다양한 DBMS에서 돌아갈수 있는 확률이 높다. (추상화되어서 이식성이 높다.)

2. Django ORM

시나리오 1

포스트들에 대헤 주어진 어트리뷰트에 대해 검색과 정렬을 처리하는 비즈니스 로직이 필요하다.

if semester is not False:
        queryset = queryset.filter(semester__in=semester)

만약 SELECT * FROM TABLE WHERE VALUE IN (1, 2, 3) 같은것을 처리하려면 원하는 어트리뷰트에 __in을 붙여서 다음과 같이 구현할수 있다.

queryset = queryset.filter(
    Q(professor=professorName),
    Q(subject__contains=subject),
    Q(id__in=[bookmark.post.id for bookmark in BookMark.objects.all().filter(user=request.user)]),
    Q(haveAnswer=True),
    Q(professor=professorName),

기존의 filter 메소드는 query 인자를 하나밖에 받지 못한다. 따라서 여러 query를 처리 하기 위해선 filter().filter().. 의 chaining를 사용해야 했다.

그러지말고 다음과 같이 Q를 활용하여 filter나 get연산시 복잡한 Query를 처리해보자 콤마(,)를 통해 and를 나타내고 (|)를 통하여 or를 나타낸다.

class Round(Func):
    function = "ROUND"
    template = "%(function)s(%(expressions)s::numeric, 1)"

queryset = queryset.annotate(
    star=Coalesce(Round(Avg('comments__star')), 0.0))
        
if sort is False or sort == 'recently': 
    queryset = queryset.order_by('-year')
else: 
    queryset = queryset.order_by('-star') #차후에 구현한다.
return queryset

사용자의 요구에 따라 최근에 만들어진순이나 평점순으로 정렬하여 반환하게 하고 싶은데 만약 평점을 매긴 사람이 아무도 없다면, null이 되어 평점순으로 정렬이 안되는 문제점이 있었다. 이를 해결하기위해 Coalesce()를 사용하였다.

Coalesce는 리스트를 순차적으로 탐색하여 null이 안나오는 최초의 값을 반환한다. 이를 이용해 Avg()를 통해 얻은 평균값이 null이면 0.0이 반환되도록 맨들었다 호호

정렬의 경우 DESC로 하고 싶으면 어트리뷰트앞에 -를 붙여서 order_by(‘-star’)와 같이 해주면 된다.

Leave a comment