🏗️

3. RDS 데이터베이스 연결

Created
2020/12/26 04:40
Tags
이제 Django 프로젝트를 실행시킬 수는 있지만, 연결되어 있는 데이터베이스가 마땅하지 않아 제대로 작동할 수 없다. 그러니 이번에는 역시 아마존의 RDS(Relational Database Service)를 통해 데이터베이스를 생성하고, 인스턴스에 연결해보도록 한다.
이번 프로젝트에서는 PostgreSQL을 이용한다. MySQL을 써보려 했지만, charset 설정이나 strict mode 등 귀찮은 일들이 많다. 생성과 연결 자체는 다른 DB도 크게 다르지 않으리라 믿는다.

데이터베이스 생성

인스턴스 생성 아래의 체크리스트를 이용해 아마존 RDS에서 데이터베이스 인스턴스를 생성한다.
엔진 옵션: PostgreSQL (취향에 맞게)
탬플릿: 프리 티어 (취향에 맞게)
Master username 및 password 설정
퍼블릭 액세스 가능성: 예
보안 그룹의 Inbound 규칙에 5432(MySQL의 경우 3306) 포트와 현재 IP(혹은 모든 IP) 추가
데이터베이스 생성 생성된 RDS 인스턴스에 접속해 프로젝트에서 이용할 데이터베이스를 생성한다. 나와 같은 경우에는 인스턴스 생성 시 초기 database name을 지정하여, 데이터베이스를 생성할 필요는 없었다. 이 건 저번에 MySQL에서 삽질했던 이야기... MySQL 역시 필요 없을 수도 있다.
Datagrip과 같은 프로그램 혹은 터미널을 통해 접속이 가능하다. 터미널을 통해 접속할 경우 psycopg2 혹은 mysqlclient가 설치되어 있어야 한다.
mysql -h[ENDPOINT] -P3306 -u[USERNAME] -p
Plain Text
복사
접속한 후 다음의 명령어로 데이터베이스를 생성하자.
CREATE DATABASE [DATABASE_NAME]
Plain Text
복사
트러블슈팅
퍼블릭 액세스 가능성을 열어놓지 않으면 로컬 컴퓨터에서 DB에 접근할 수 없다.
보안 그룹의 Inbound 규칙에 해당(혹은 모든) IP에 대한 해당 포트로의 접근을 허용하지 않으면 역시 접속할 수 없다. 프로덕션 환경에서는 모든 IP에 대한 접근을 허용하지는 말자.
PostgreSQL의 경우에는 초기 DB name을 지정하기 않으면 default는 postgres 이다.

데이터베이스 연결

이제 데이터베이스를 생성했으니, 연결하기만 하면 된다. 우선 PostgreSQL과 Django를 연결하기 위해서는 psycopg2 라는 패키지가 필요하다. 참고로 MySQL과 Django를 연결하기 위해서는 mysqlclient 라는 패키지가 필요하다. 다음의 명령어를 통해 Ubuntu 서버에 해당 패키지를 설치하자.
psycopg2 설치 (PostgreSQL의 경우)
sudo apt-get install libpq-dev python-dev pip install psycopg2
Plain Text
복사
mysqlclient 설치 (MySQL의 경우)
sudo apt-get install libmysqlclient-dev pip install mysqlclient
Plain Text
복사
Django settings 변경: DATABASES를 추가해 준다.
# settings/deploy.py ... DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', # 혹은 mysql 'NAME': config_secret_deploy['django']['databases']['name'], 'USER': config_secret_deploy['django']['databases']['user'], 'PASSWORD': config_secret_deploy['django']['databases']['password'], 'HOST': config_secret_deploy['django']['databases']['host'], 'PORT': '5432', # MySQL의 경우 3306번 포트를 이용한다. 'OPTIONS': { 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'" # MySQL의 경우에만 필요하다. } } } ...
Python
복사
위 코드를 보면 MySQL의 경우에는 OPTIONS 라는 key 안에 init_commandSET sql_mode='STRICT_TRANS_TABLES 로 정의되어 있는 것을 확인할 수 있다. Database 차원에서 데이터의 무결성을 확보해주는 것 같다. 아무튼 이 strict mode가 설정되어 있지 않으면 Django에서 migration을 거부하니, 쉬운 인생을 위해 지금은 설정해 주도록 하자.
트러블슈팅
MySQL 특정 버전 이후로는 database의 기본 설정이 utf8 이 아닌 latin 으로 되어있는 것 같다. 이로 인해 DB에 한글로 된 데이터를 쓰려고 하면 Internal Server Error를 준다.
이를 해결하기 위해서는 my.cnf 파일을 수정하고, 데이터베이스의 charset 역시 수정해줘야 하는 것 같다. 자세한 방법은 모르겠다. 나는 그냥 PostgreSQL을 쓰기 시작했다.

Migration

이제 이론적으로 Django 프로젝트와 데이터베이스는 연결되어 있다. 하지만 Django 프로젝트를 제대로 작동시키기 위해서는 데이터베이스를 Django 프로젝트의 모델에 맞게 migration해야 한다.
django migration을 통해 아주 간단하게 프로젝트에서 사용할 데이터베이스 테이블을 생성할 수 있다.
python manage.py makemigrations python manage.py migrate
Plain Text
복사
트러블슈팅 하지만 나의 경우에는 Django 프로젝트 내에서 Custom User Model을 사용하였고, 이로 인해 migrate 명령어는 다음과 같은 에러 메시지를 뱉어 냈다.
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency api.0001_initial on database 'default'.
Plain Text
복사
장고에 내장된 User 모델과 Custom된 User 모델이 충돌을 일으키는 것 같다. 이를 해결하기 위해서는 (initial migration이라는 전제 하에) 직접 선언한 모델이 포함된 app의 migration을 우선적으로 진행해 주어야 한다.
만약 진행한 migration이 있다면,
데이터를 백업한 상태에서 database를 drop한 후 다시 생성하고 (DROP DATABASE [DATABASE_NAME])
프로젝트 폴더 내의 __init.py__ 파일을 제외한 모든 migration 파일을 삭제한 후 아래의 코드를 진행하는 것을 추천한다.
python manage.py makemigrations python manage.py migrate [YOUR_APP] # 직접 선언한 모델을 먼저 migrate한다. python manage.py migrate # 이후에 내장 모델들을 migrate한다.
Plain Text
복사
E.O.D.