django 019 | On PostgreSQL only, you can pass positional arguments (*fields) - Django에서 postgresql 사용하기

This Is Empty.·2021년 10월 17일
0

Django

목록 보기
20/20

갑자기 Postgres로 바꾸게 된 이유

H&M 클론 코딩을 진행 하던 중, 상품을 필터링해서 보내주는 과정을 프론트와 통신해서 확인하던 중 고쳐야할 부분을 발견했다.

우리가 작성한 products 모델은 상품 번호는 다르고, 상품 이름은 같은것이 존재한다. 이렇게 만든 이유는 H&M 사이트에서 제품을 클릭해보면 제품 번호를 알려주는데


같은 제품이지만 컬러가 다른 제품은 제품 번호도 다르게 표시되어 있다.

처음에는 단순히 필터링만 해서 보내줬고, 코드는 다음과 같았다.

Query String으로 들어온 필터링 조건이 FILTER_PREFIX에 존재하면 Product 객체에서 조건에 맞는 상품만 리턴해서 보여준다.

이 경우에 필터링은 잘 작동하지만 프론트와 통신 후에 살펴보면 필터링 후 같은이름을 가진 상품이 컬러가 달라 id가 다를 경우 바로 옆에 위치하게 된다.

물론 클릭후 상세페이지를 살펴보면 분명 다른 제품인것은 맞지만 보기에는 좀 그렇다.
사실 모델링부터 문제가 있었던것은 맞다. 연관제품 테이블을 만들었으면 해결될 일이였는데, 당장 2일 안에 프로젝트를 마무리 지어야했고 테이블을 건드리면 작성되어있는 다른 뷰들도 건드려야했고 csv파일과 db_uploader.py.. 엮여있는 문제가 너무 많았다.

원래 raw SQL은 컬럼명으로 distinct가 가능하다. 그래서 될 줄 알았다. distinct(*field)를 사용해 보았는데.. 에러를 반환했다. 에러 사진을 찍어둔게 없어서 첨부는 못하지만 긁어서 구글링 해보니 다음과 같은 내용을 발견했다.

여기에서 확인하면 대충 네가 구현하고 싶은 기능은 Postgresql 에서만 가능해 라고 쓰여있다..

멘토님에게 달려가 SOS를 요청했다. 답은 딱 두개로 정해져 있었다.

  1. mysql db를 쓰면서 raw SQL로 해당 기능을 구현
  2. Postgresql로 변경하고 distinct 기능 사용

raw sql 작성법을 모르는것은 아니였지만 후자보다 시간이 더 오래 걸릴것 같았다.
전에 postgresql을 사용해본 경험이 있었는데 mysql과 크게 다르지 않다고 생각해 그냥 2번을 선택했다.

django에서 postgres 사용하기

다음의 명령어로 Postgresql을 설치한다.

brew install postgrsql
brew services start postgresql


설치가 잘 되었다면 위 명령어로 버전 확인이 가능하다.

psql postgres

위 명령어로 postgresql에 접속 후 아래 명령으로 미리 정의된 권한을 확인한다.

postgres=# \du

다음 명령어로 postgres 유저의 비밀번호를 설정 할 수 있다

postgres=# \password postgres

다음 명령어로 데이터 베이스를 생성한다.

CREATE DATABASE "db-name"
  WITH OWNER "db-user"
  ENCODING 'UTF8'
  LC_COLLATE = 'en_US.UTF-8'
  LC_CTYPE = 'en_US.UTF-8';

다음 명령어로 생성한 db에 접속 가능하다

 postgres=# \connect [db-name]

mysettings.py를 다음과 같이 수정하여 Postgres database를 사용한다.

DATABASES = {
    'default' : {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'db-name',
        'USER': 'db-user',
        'PASSWORD': 'PASSWORD',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

migrate와 원래 작성한 db_uploader.py는 문제없이 작동한다.

수정한 filtering 코드

원래 코드보다 수정된 사항은 다음과 같다.

  • offset & limit를 사용한 pagenation
  • distinct를 사용한 중복 상품 제거
  • filtering시 size_id가 아닌 size_name 사용
profile
Convinced myself, I seek not to convince.

0개의 댓글