본문 바로가기
Django

Django와 postgreSQL 연동하기

by 개발자54 2022. 11. 30.

Django와 postgreSQL 연동에 관한 포스트를 찾아보면

대부분이 연동 후에 models.py 작성을 통해 "새로운" 모델을 생성하는 것에 관해 설명한다.

그러나 나의 경우 기존의 DB를 Django의 모델로 옮겨와야 했으므로

위와 같은 방법을 사용하는 것은 적절하지 않았다.

따라서 기존의 DB 데이터를 Django로 가져와서 관리자 페이지에서 조회하기까지 진행해보겠다.

파이썬과 파이참, postgreSQL은 기본적으로 설치되어 있다고 가정한다.

postgreSQL 설치 방법은 https://fotia.tistory.com/2 참고

 

 


 

1. 파이참 터미널을 열어 django 설치, 설치 확인, config 폴더에 django 프로젝트 생성

$ pip install django
$ python -m django --version
$ django-admin startproject config .

두 번째 줄의 명령어를 입력했을 때 파이썬 버전이 뜨지 않는다면 설치가 제대로 되지 않은 것이다.

세 번째 줄의 명령어의 경우 config라는 폴더에 장고 프로젝트 파일들을 만들겠다는 의미이며,

명령어를 입력할 때 config 뒤에 공백이 반드시 있어야 작동함에 유의.

(폴더 이름이 반드시 config일 필요는 없으나, 프로젝트 생성 후에 변경하려면 번거롭기 때문에

웬만하면 바꾸지 않도록 처음부터 폴더 이름을 잘 정할 것)

제대로 django 프로젝트가 설치되었다면 config 폴더와 manage.py 파일이 생성됨을 확인할 수 있다. 파일 하나하나에 대한 설명은 생략.

 

 

2. 파이썬과 postgreSQL을 연동

$ pip install psycopg2

※ 만약 이 코드를 입력하고 4번으로 진행했는데

Library not loaded: '@rpath/libpq.5.dylib'와 같은 오류가 난다면,

$ brew update
$ pip install psycopg2-binary --force-reinstall --no-cache-dir

을 추가적으로 진행해준다.

 

 

3. config/settings.py 파일 수정

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "rcp",
        "USER": "seojaewon",
        "PASSWORD": "admin",
        "HOST": "localhost",
        "PORT": "5432"
    }
}

config/settings.py 파일의 DATABASES 부분을 찾아서, 기존 postgreSQL의 정보를 위와 같이 입력해준다.

나 같은 경우 기본 세팅이 ""(큰 따옴표)로 되어 있는데 ''(작은 따옴표)여도 문제는 없다.

  • ENGINE : 어떤 종류의 데이터베이스를 사용할 지 설정하는 부분
  • NAME : 데이터베이스의 이름
  • USER : 데이터베이스의 ROLE NAME(OWNER) 이름. ROLE NAME을 잘 모르겠다면 https://fotia.tistory.com/2 의 4번을 참고하여 조회할 것
  • PASSWORD : USER에 설정한 비밀번호
  • HOST : 접속하고자 하는 네트워크 노드 IP의 주소 (공부용, 개인용으로 사용할 땐 대부분 localhost)
  • PORT : 컴퓨터에서 실행되고 있는 서버를 구분 짓기 위한 16비트의 논리적 할당값 (postgreSQL은 관습적으로 5432 사용)

 

 

4. 기존 DB의 정보를 바탕으로 models.py 파일 생성

$ python manage.py inspectdb > models.py

위 명령어를 입력하면 기존 DB의 정보를 싹 다 긁어온 클래스들을 모은 파이썬 파일이 생성된다.

기존 DB에 있던 테이블의 이름이 rcp_table이라면 RcpTable 클래스로 자동으로 만들어진다.

models.py를 확인하여, 가져오고 싶은 테이블의 클래스명을 기억해두면 된다.

나는 RcpTable의 데이터를 가져올 것이다. 

여기서 중요한 것은 기본키 설정이다. (DB에 기본키 설정을 해둔 사람이라면 바로 5번으로 넘어가도 된다.)

웬만하면 문제가 없겠지만, 나는 DB를 생성할 때 DB 내에 기본키를 설정해두지 않고 진행해서 오류를 맞닥뜨렸다.

그 외에도 DB의 스키마 구조가 저 명령어로 모두 반영되는 것이 아니므로, 수정해야할 사항이 있다면 수정하도록 하자.

 

나 같은 경우 하단 코드처럼 RcpTable 클래스에 기본키 설정이 아예 없었는데,

class RcpTable(models.Model):
    rcp_pk = models.IntegerField()
    rcp_nm = models.CharField(max_length=100, blank=True, null=True)
    rcp_sub_nm = models.CharField(max_length=100, blank=True, null=True)

...

    class Meta:
        managed = False
        db_table = 'rcp_table'

 

아래 코드처럼 기본키를 명시해주었다. (primary_key=True)

class RcpTable(models.Model):
    rcp_pk = models.IntegerField(primary_key=True)
    rcp_nm = models.CharField(max_length=100, blank=True, null=True)
    rcp_sub_nm = models.CharField(max_length=100, blank=True, null=True)

...

    class Meta:
        managed = False
        db_table = 'rcp_table'

 

 

5. MTV 패턴을 적용한 앱 생성

$ python manage.py startapp rcp

MTV 패턴이란 Model, Template, View를 의미하며 이는 다른 포스팅에서 추후 다뤄보도록 하겠다.

명령어를 실행하면 rcp라는 폴더(앱)가 만들어진 것을 확인할 수 있다.

 

 

6. config/settings.py에 rcp 추가

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rcp"
]

config/settings.py 파일의 INSTALLED_APPS 부분을 찾아서, 방금 만든 rcp 앱을 추가해준다.

 

 

7. rcp 어플리케이션의 models.py 파일을 업데이트

4번에서 생성했던 rcp 프로젝트 루트의 models.py 파일을 rcp 폴더(앱) 안으로 옮겨서 덮어씌운다.

 

 

8. 마이그레이션

$ python manage.py makemigrations
$ python manage.py migrate

 

첫 번째 명령어를 실행하면 하단과 같이 rcp 앱 안의 migrations 폴더 안에 0001_initial.py라는 폴더가 생성되고,

두 번째 명령어를 실행하면 관리자 계정 생성을 위한 테이블 세팅이 완료된다.

참고로 두 번째 명령어를 생략하게 될 경우 관리자 계정 생성이 불가능하다.

첫 번째 명령어를 실행한 뒤 파일이 생성된 모습
postgreSQL 클라이언트 툴을 사용하고 있다면, 두 번째 명령어를 실행한 후에 클라이언트 툴로 가게 되면 처음 보는 테이블들이 잔뜩 생겨나 있는 것을 확인할 수 있다. 나 같은 경우 TablePlus라는 클라이언트 툴을 사용하고 있다.

 

 

9. rcp/admin.py에 모델 등록

from django.contrib import admin

from .models import RcpTable

# Register your models here.
admin.site.register(RcpTable)

 

 

10. 관리자 계정 생성

$ python manage.py createsuperuser

차례대로 유저 이름, 이메일 주소, 비밀번호, 비밀번호 확인을 입력해준다.

비밀번호를 입력할 때는 화면에 입력값이 나타나지 않음에 유의

 

 

11. 서버 실행하여 데이터 조회

$ python manage.py runserver

위와 같은 메시지가 뜬다면 서버 구동에 성공한 것이다.

파란 밑줄이 그어져 있는 링크를 클릭해 들어가보면 하단과 같은 화면을 확인할 수 있다.

주소의 끝에 admin을 입력하여 http://127.0.0.1:8000/admin/ 으로 접속해보면,

하단과 같은 관리자 화면을 확인할 수 있다.

Rcp tables를 클릭하면, 데이터들이 잘 조회가 된다.

비록 object라는 이름으로 먼저 접할 수 있고, 아직 예쁘게 데이터가 보이는 형태는 아니지만,

object를 하나씩 클릭하면 테이블에 있는 데이터가 그대로 반영되어 조회할 수 있음을 확인할 수 있다.

추가, 수정, 삭제도 정상적으로 작동함을 확인할 수 있다.

 

관리자 페이지에서 조회, 추가, 수정, 삭제 기능을 이용할 수 있지만

제대로 된 서비스를 제공하기 위해서는 프론트에서도 이 기능이 작동해야 할 필요가 있다.

따라서 다음 포스트에서는 프론트에서 조회, 추가, 수정, 삭제 기능을 구현해보도록 하자.

 

 

번외. __str__ 메서드를 이용하여 관리자 페이지의 object 데이터를 원하는 형식으로 출력

__str__ 메서드 : 클래스의 오브젝트를 출력할 때 나타낼 내용을 결정하는 메서드로, 항상 문자열을 반환

11번의 관리자 페이지 Rcp table 리스트를 보면,

제목이 RcpTable object (숫자)의 형식이어서 무슨 데이터인지 한번에 알아보기 쉽지 않다.

fst 앱의 models.py에 __str__ 메서드를 추가해서 내가 원하는 데이터 형식으로 출력할 수 있다.

__str__ 메서드를 활용하여 레시피명 : 어쩌구저쩌구의 형태로 출력해보자.

from django.db import models

class RcpTable(models.Model):
    rcp_pk = models.IntegerField(primary_key=True)
    rcp_nm = models.CharField(max_length=100, blank=True, null=True)
    rcp_sub_nm = models.CharField(max_length=100, blank=True, null=True)
    rcp_ingrdnt_nm = models.CharField(max_length=50, blank=True, null=True)
    rcp_ingrdnt_qnt = models.CharField(max_length=50, blank=True, null=True)
    rcp_ingrdnt_msmt = models.CharField(max_length=50, blank=True, null=True)
    rcp_ingrdnt_qnt_sub = models.CharField(max_length=50, blank=True, null=True)
    rcp_ingrdnt_qnt_sub2 = models.CharField(max_length=50, blank=True, null=True)
    rcp_ingrdnt_qnt_sub3 = models.CharField(max_length=50, blank=True, null=True)
    rcp_ingrdnt_qnt_sub4 = models.CharField(max_length=50, blank=True, null=True)
    rcp_ingrdnt_qnt_sub5 = models.CharField(max_length=50, blank=True, null=True)

    # 추가한 코드 부분
    def __str__(self):
        return "레시피명 : " + self.rcp_nm
    # 추가한 코드 부분 끝

    class Meta:
        managed = False
        db_table = 'rcp_table'

원하는 형식대로 출력되었음을 확인할 수 있다.

 

댓글