[Django] Django Postgres 연결하기

유나니·2020년 10월 10일
3

python_til

목록 보기
2/2

Intro

django는 프로젝트 생성 시 기본 데이터베이스로 sqlite3을 제공한다. 간단히 로컬에서 만들고 테스트하기에는 상당히 편한 옵션이지만 같은 데이터를 바탕으로 협업을 하기에는 부적합한 방식이다. 또한 monotolic한 아키텍처가 아닌 기능별로 프로젝트 파일이 분리된 MSA 스타일의 개발 시에도 각각의 프로젝트에 DB를 따로 두는 것은 적절하지 않다.(기능 30개면 sqlite가 30개...)

따라서 sqlite3이 아닌 mysql 혹은 postgres DB와 django를 연결하는 방법에 대해 필요성을 느끼고 포스팅을 하고자 한다.

AWS EC2에 Postgres 띄우기

로컬 환경에서 postgres를 설치해 연동해도 되지만 EC2 인스턴스가 있고 도커가 그 위에 설치되어 있다는 전제 하에 포스팅을 진행하고자 한다. 다들 아시겟지만 권한 문제로 도커 명령어 실행이 안된다면 sudo docker 로 실행한다. 그것도 귀찮으면 sudo su 로 관리자 권한으로 실행하면 sudo 명령어 없이 도커가 실행된다.

postgres 이미지 다운받기

$ (sudo) docker pull postgres

sudo docker images 를 실행해 보면 postgres 이미지가 빌드되어 있는 것을 확인할 수 있다.

생성한 이미지를 컨테이너 위에 띄우기

$ docker run -d -p 5432:5432 --name <생성하려는 컨테이너명: 예) pjt2> -e POSTGRES_PASSWORD=mysecretpassword postgres

5432포트(포스트그레의 디폴트)에 해당 비밀번호를 가지고 pjt2라는 이름을 가진 포스트그레 컨테이너를 postgres라고 빌드된 이미지를 실행하라는 의미 정도로 이해하면 되겠다.

sudo docker ps 를 실행해 보면 postgres 이미지가 올라와 있는 컨테이너를 확인할 수 있다.

이후 5432번 포트에는 postgres가 할당되어 돌아가고 있다.

컨테이너 postgres에 데이터베이스 생성하기

$ docker exec -it <생성된 컨테이너명> bash
$ root@<container ID>:/# psql -U postgres

해당 명령어를 통해 컨테이너 내부의 배시창으로 접근이 가능하다. 해당 배시창에서 psql -U postgres 로 postgres bash 창으로 접속한다. 이제 django에서 사용할 데이터베이스를 만들어보자

-- 데이터베이스 생성 이후 해당 데이터베이스로 접속
CREATE DATABASE <데이터베이스명>;
postgres=# \c <데이터베이스명>
-- 이때 비밀번호는 따옴표로 감싸주어야 함.
CREATE user <유저명> with password 'password';

-- 인코딩 형식은 utf-8로 세팅한다.
ALTER role root SET client_encoding to 'utf-8';


ALTER role root SET timezone to 'Asia/Seoul';
GRANT all privileges ON database <데이터베이스명> to <유저명>;

EC2 인스턴스의 기본 타임존은 en-us이기 때문에 장고와 연동 시 시간 설정을 하지 않으면 데이터가 디비에 저장되는 시간이 외국 시간으로 기록되어 저장된다. 이는 게시글 혹은 댓글기능을 구현할 때 중요한 이슈가 되기 때문에 데이터베이스의 타임존을 한국시간으로 맞춰준다.

다만 이것은 EC2 인스턴스 타임존과는 관계 없이 EC2 인스턴스 위에 띄운 컨테이너(포스트그레) 안의 특정 데이터베이스의 타임존 만을 바꿔준 것이다.

이후 데이터베이스의 수정/삭제/생성 등의 권한을 생성한 유저에게 넘겨주면 기본 세팅이 완료된다.

장고에 postgres 연동하기

settings.py 에는 데이터베이스와 관련된 설정 또한 포함되어 있다. 이 중에서 DATABASE 를 찾아보면 sqlite3으로 디폴트가 되어 있는 것을 확인할 수 있다. 이 부분을 바꿔보도록 하자

그 전에 우선 설치해야 할 파이썬 모듈이 있다. psycopg2-binary 인데 쉽게 말하자면 장고는 ORM 베이스로 돌아가는데 기존 sqlite에서는 orm이 잘 돌아갔지만 postgres로 바꿀 예정이기 때문에 postgres가 ORM을 이해하고 데이터를 가져오게 해야 한다. 이 과정을 수행하기 위해 필요한 모듈 정도로 생각하면 좋을 것 같다. pip install psycopg2-binary 로 설치해 주고 이미 배포를 한 상태라면 requirements.txt 에 한 줄 적어주자

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': config('POSTGRES_NAME'),
        'USER': config('POSTGRES_USER'),
        'PASSWORD': config('POSTGRES_PASSWORD'),
        'HOST': config('POSTGRES_HOST'),
        'PORT': config('POSTGRES_PORT'),
    }
}

엔진을 sqlite3에서 postgresql로 바꿔주고, 방금 생성했던 name(데이터베이스명), user(유저명), password를 기억해 잘 적어주고 host 부분에 각자 ec2의 호스트명(보통 IP)을, 포트번호(포스트그레 디폴트는 5432) 적어준다.

하지만 이렇게 민감한 정보들을 그대로 적어서 깃 같은 데에 올라가면 대형사고가 발생한다. 그래서 민감 정보들을 숨기는 방법에 대해 잠깐 이야기하고자 한다.

python decouple 모듈 활용해 민감정보 숨기기

$ pip install python-decouple

설치 후 settings.py 에서 해당 모듈을 불러온다. 데이터베이스와 관련된 민감 정보를 숨기는 김에 장고의 시크릿키도 같이 숨겨보자.

from decouple import config
SECRET_KEY = config('SECRET_KEY')

그렇다면 어디서 찾아서 가져오느냐 하는 당연한 의문을 가질 것이다. 바로 이렇게 숨길 수 있다. Ini 파일을 만들고 다음과 같은 형식으로 내용을 채우면 된다. 여기까지 다 해놓고 막상 ini 파일을 .gitignore에 넣는것을 깜빡하면 절대 안된다!!!!!!

settings.ini

[settings]
SECRET_KEY=ajlsdkfjla;sdjf;lasdjfl;ajdsfl;ajdsl;f
POSTGRES_NAME=pjt2
POSTGRES_USER=unani
POSTGRES_PASSWORD=password
POSTGRES_HOST=hostname
POSTGRES_PORT=5432

이제 다 끝났다. 디비 연결까지 끝났으니 마이그레이션을 해주어 테이블을 생성하고 스키마를 입혀주는 과정만 하면 배포용 EC2 인스턴스의 도커 위에 있는 postgres의 데이터베이스에서 장고의 모델을 연동해 사용할 수 있다.

$ python manage.py makemigrations
$ python manage.py migrate
profile
User First, Mobile Friendly

0개의 댓글