Django : python으로 웹서비스 개발하기(7) - 테이블 모델을 통해 스키마 구성하기

harry jang·2023년 7월 12일
0

Django

목록 보기
7/12
post-thumbnail

모델 직접 만들어보기

지난 번에는 DB에 수동으로 테이블을 생성한 뒤 inspectdb 명령을 통해서 만들어진 모델을 이용해서 테이블에 데이터를 삽입해 봤다면, 이번에는 모델을 통해 테이블 생성 및 데이터 삽입하는 방법을 알아보겠습니다.

먼저 models.py에 신규로 생성할 테이블의 모델을 추가합니다.

from django.db import models

...
class TestBookCategory(models.Model):
    categoryName = models.CharField(max_length=20)
        
class TestBook(models.Model):
    title = models.CharField(max_length=200)
    category = models.ForeignKey(TestBookCategory, on_delete=models.SET_NULL, null=True)
    price = models.IntegerField()
    reg_datetime = models.DateTimeField()
...

데이터베이스의 각 필드는 Field클래스의 인스턴스로 표현합니다. 이 작업을 통해 각 필드가 어떤 자료형을 가질 수 있는지를 Django에게 말해줍니다.

  • CharField : 문자(character)형 타입 필드

  • DateTimeField : 날짜와 시간형 타입 필드

  • IntegerField : 정수형 타입 필드

  • AutoField : 자동증가하는 정수형 타입 필드, 주로 pk를 저장할 때 사용하지만 django 내부적으로 id라는 컬럼을 자동생성하므로, A model can't have more than one AutoField 에러가 발생할 수 있습니다. 이를 방지하려면 id를 생성하지 않고 해당 필드가 PK가 되도록 primary_key=True옵션을 추가해야 합니다.

    ex) category_id = models.AutoField(primary_key=True)

이 외의 필드 타입에 대한 내용은 다음 링크를 참고하여 사용하도록 합니다.

ForeignKey 클래스를 통해 테이블 간의 관계를 설정할 수도 있습니다.
Django 는 다-대-일(many-to-one), 다-대-다(many-to-many), 일-대-일(one-to-one) 과 같은 모든 일반 데이터베이스의 관계들를 지원합니다.

모델 활성화하기

이 모델을 통해 Django에서는 다음과 같은 작업을 진행합니다.

  • 이 앱을 위한 데이터베이스 스키마 생성(CREATE TABLE 문)
  • TestBook과 TestBookCategory 객체에 접근하기 위한 Python 데이터베이스 접근 API를 생성

위 작업을 하기 위해 먼저 test_project프로젝트 내 settings.py파일의 INSTALLED_APPS에 앱의 구성 클래스에 대한 참조를 추가하여 test_app앱이 설치되어 있다는 것을 알려줍니다.
이 구성 클래스는 앱이름 + Config이라는 이름으로 생성되어 있으며, test_app/apps.py파일 내에 존재합니다.
이 내용을 바탕으로 INSTALLED_APPS에 구성 클래스를 추가합니다. (이전 포스팅에서 test_app 패키지를 통으로 넣어줬다면 별도로 작업하지 않아도 됩니다.)

INSTALLED_APPS = [
    "test_app.apps.TestAppConfig",
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Django에 test_app앱이 포함된 것을 알려줬다면 다음 명령을 실행합니다.

$ python manage.py makemigrations test_app

makemigrations 을 실행하게 되면 모델을 생성 혹은 변경시킨 사실과 이 변경사항을 migration으로 저장시키고 싶다는 것을 Django에게 알려주게 됩니다.

Migration은 Django가 모델(즉, 데이터베이스 스키마)의 변경사항을 디스크에 저장하는 방법입니다.
test_app/migrations/0001_initial.py파일에 변경된 새 모델에 대한 migration을 읽어 볼 수 있습니다. 이 파일을 직접 수정할 수 있도록 설계가 되어 있어 Django의 변경점을 수동으로 수정할 수도 있습니다.

다음으로 sqlmigrate 명령을 통해 Migration이 내부적으로 어떤 SQL 문장을 실행하는지 살펴 볼 수 있습니다.

$ python manage.py sqlmigrate test_app 0001

저의 경우에는 MySQL을 연동하여 다음과 같이 쿼리가 표시되며 이 내용은 연동하는 DB마다 다를 수 있습니다.

sqlmigrate은 실제로 DB에 마이그레이션이 되지 않고 화면에 출력해줍니다. 단지 마이그레이션에 사용할 SQL문을 보여주는 것이며, 내가 작성한 테이블 모델이 어떻게 db에 마이그레이션이 될지 확인하는 용도로 유용하게 사용할 수 있습니다.

--
-- Create model TestBookCategory
--
CREATE TABLE `core_testbookcategory` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `categoryName` varchar(20) NOT NULL);
--
-- Create model TestBook
--
CREATE TABLE `core_testbook` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(200) NOT NULL, `price` integer NOT NULL, `reg_datetime` datetime(6) NOT NULL, `category_id` bigint NULL);
ALTER TABLE `core_testbook` ADD CONSTRAINT `core_testbook_category_id_11be1c0d_fk_core_testbookcategory_id` FOREIGN KEY (`category_id`) REFERENCES `core_testbookcategory` (`id`);

sqlmigrate로 출력된 쿼리를 실제로 적용하려면 migrate 명령을 사용합니다.

$ python manage.py migrate

migrate 명령은 아직 적용되지 않은 마이그레이션을 모두 수집해서 실행하며, 이 과정을 통해 모델에서의 변경 사항들과 데이터베이스의 스키마의 동기화가 이루어집니다.

django의 이 강력한 기능은 DB나 테이블을 거의 직접 다루지 않고도 모델을 생성하고 반복적인 변경도 가능하게 해줍니다. 게다가 동작 중인 데이터베이스를 자료 손실 없이 업그레이드하는데 최적화 되어 있습니다.

이 일련의 작업들이 복잡해 보일 수도 있지만 이 단계만 기억하면 됩니다.

  1. models.py 에서 모델을 변경합니다.
  2. makemigrations을 통해 이 변경사항에 대한 마이그레이션을 생성합니다.
  3. migrate명령을 통해 변경사항을 데이터베이스에 적용합니다.
profile
software engineer

0개의 댓글