TIL17. 모델 작성과 ORM
스타벅스 웹페이지 모델링한 것을 토대로 모델을 작성하고 데이터를 생성해 볼 것이다.
1. 장고 기본 세팅
스타벅스 프로젝트를 생성하고 기본 환경설정을 해준다.
1-1 장고 초기 세팅
- 데이터베이스 생성 : MySQL에 들어가 새로운 데이터베이스를 생성한다.
- 파이썬 패키지 설치 : 가상환경에서 django, mysqlclient를 설치한다.
- 프로젝트 생성 : 스타벅스 프로젝트를 생성하고 해당 디렉토리로 이동한다.
settings.py
설정 :INSTALLED_APPS
,MIDDLEWARE
에서 필요없는 것들은 주석처리 해준다. 데이터베이스와 시크릿키는 중요한 정보로 따로 관리해주는 것이 좋다.my_settings.py
생성과 설정 :manage.py
와 같은 경로에서my_settings.py
를 만들어주고 여기에 데이터베이스와 시크릿키를 입력한다.settings.py
에서는my_settings.py
의 데이터베이스와 시크릿키를 연결해준다.- corsheaders 설치 : 설치 후
INSTALLED_APPS
에 추가한다.
서버가 잘 동작하는지 체크해본다.
1-2 깃헙 연동
깃헙에 올리기 전에 중요하거나 불필요한 파일들은 .gitignore
에 입력해준다. my_settings.py
도 추가한다. 프로젝트를 로컬 레퍼지토리에 올린다. 깃헙 레퍼지토리를 생성 후 로컬 레퍼지토리와 연동시킨다.
git branch -M main
: 초기 branch가 master 라면 main 으로 변경해준다.
이제 main branch에서의 작업은 끝났다. 다른 기능을 추가하고 싶다면 새로운 branch에서 작업하는 것이 좋다.
2. 모델 작성
스타벅스 메뉴에 대한 브랜치 featrue/crud
와 앱 products
를 새로 생성한다. 앱이 추가된 것을 장고에게 알리기 위해, INSTALLED_APPS
에 products
를 추가한다. 이후 products/models.py
에서 모델링한 내용을 작성한다.
각각의 테이블은 클래스로 작성한다. 클래스가 어떻게 MySQL에서 테이블로 변환되는 것일까? 둘의 관계를 연동시키는 작업을 ORM 이라고 하고, 장고에서는 이를 자동으로 처리하여 우리가 할 작업을 줄여준다.
ORM Object Relational Mapping
객체와 테이블의 관계를 연결시켜주는 작업
ORM 참조
https://www.fullstackpython.com/object-relational-mappers-orms.html
2-1 테이블 작성
모든 테이블을 설명하지 않고, 테이블 관계를 중점으로 몇가지 테이블만 살펴보자.
1:1 관계
음료와 영양소. 1개의 음료 당 1개의 영양소가 존재한다. 서로 하나에만 연결되는 관계이다. 1:1 관계에서는 OneToOneField
속성을 사용한다. 둘 중 한 클래스에만 적용하면 된다. on_delete=models.CASCADE
는 참조하는 데이터가 삭제될 경우에 대한 옵션이다. 이 경우는 참조하는Products
데이터가 삭제되면 이와 연관된 Nutritions
데이터도 삭제된다.
1:N 관계
메뉴와 카테고리. 1개의 메뉴에 대해 여러 개의 카테고리가 존재한다. 1:N 관계에서는 참조하는 클래스에서 ForienKey
속성을 적용한다.
N:N 관계
음료와 알러지. 1개의 음료에 여러 개의 알러지가 있고, 여러 개의 음료에 1개의 알러지가 해당할 수 있다. N:N 관계를 정의하는 것은 2가지 방법이 있다.
1. 중간 테이블 생성
둘 중 한 클래스에 ManyToManyField
속성을 적용하고, through
에 중간 클래스 이름을 넣는다.
중간 클래스의 이름은 보통 클래스1_클래스2
로 정의한다. 그리고 연결될 2개의 클래스에 대해 각각 ForeignKey
를 적용한다.
2. 중간 테이블 없음
중간 테이블 없이 N:N 관계를 정의하려면, 한 클래스에 ManyToManyField
속성을 적용하고 다른 클래스 이름을 넣는다. 실제 데이터를 생성할 때에 그들의 관계가 실질적으로 연결된다.
# 음료와 알러지 테이블 정의
class Products(models.Model):
name = models.CharField(max_length=45)
.
.
class Allergies(models.Model):
name = models.CharField(max_length=45)
product = models.ManyToManyField(Products)
.
.
# django shell에서 음료와 알러지 데이터에 대해 변수와 save를 사용하여 생성한다.
p1 = Products(name="콜드 브루")
p1.save()
p2 = Products(name="카페 라떼")
p2.save()
a1 = Allergies(name="우유")
a1.save()
# 알러지 데이터 a1에 대해 음료 데이터 p1, p2를 다음과 같이 연결시킨다.
a1.products.add(p1)
a1.products.add(p2)
3. 모델 작성하며 발생한 오류
데이터베이스 migration 이후 모델을 수정해야 할 때
- 수정 사항
- 자잘한 오타나 null 여부
- 참조하는 필드의 이름에
_id
를 붙이지 않아도 된다는 점. 처음에는product_id
로 이름을 설정하였는데, 데이터베이스에는product_id_id
로 중복되어 나타남. ORM 시 자동으로 붙여준다는 것을 알게 되고 필드명 다시 수정
이러한 수정 사항을 반영한 후 다시 makemigrations
를 하니 모든 필드에 default 값을 입력하라는 메세지가 나왔다. 모델에 직접 작성하지 않은 id
도 입력해야 한다 해서, 마이그레이션 자체를 삭제하기로 결정했다.
나의 경우, 데이터베이스는 그대로 놔두고 테이블만 삭제하고 싶어서 MySQL에 다음과 같은 명령어를 입력했다.
SET @tables = NULL;
SELECT GROUP_CONCAT(table_schema, '.', table_name) INTO @tables
FROM information_schema.tables
WHERE table_schema = 'DB이름 입력'
SET @tables = CONCAT('DROP TABLE ', @tables);
PREPARE stmt FROM @tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
데이터가 없는 빈 테이블이었기 때문에 가능했지만, defalut값을 입력하지 않고 마이그레이션을 수정할 수 있는 방법을 모색하는 것이 좋을 듯하다.
Author And Source
이 문제에 관하여(TIL17. 모델 작성과 ORM), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@byoungju1012/TIL17.-모델-작성과-ORM저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)