(Django) ERD~데이터베이스

Kepler·2020년 2월 18일
3

Django

목록 보기
8/12

스타벅스의 음료를 Mysql에 저장하는 과제를 wecode 백엔드 세션에서 다음의 과정을 거쳐서 같이 해보았다.


클로닝한 페이지: https://www.istarbucks.co.kr/menu/drink_list.do
설계 부분: 대분류(음료) > 소분류(카테고리) > 음료


1. ERD (Entity Relationship Diagram) 설계

  • 테이블 설계시 사용하는 이름과 필드명은 장고에서 모델을 만들때도 사용한다.

  • 테이블명과 각필드의 이름을 정할때 convention을 따르고, 신중히 정하자.

    • 테이블 이름은 기본 소문자, 복수형, 설명적(descriptive)으로.
    • 되도록 재사용이 가능한 이름을 지정한다.
      예) drink_categories 대신 sub_categories
  • field type 선택하는 방법: validation까지 필요한 경우는 신경써서 설정해야 한다. 그렇지 않은 경우는 논리적으로 맞는 타입을 선택하면 충분하다.
    (more on field type: https://docs.djangoproject.com/en/3.0/ref/models/fields/)

  • one-to-one(일대일) or many-to-one(다대일) : 정참조, 화살표 방향이 좌변 기준 정방향.

  • one-to-many(일대다) or many-to-many(다대다) : 역참조, 화살표 방향이 좌변 기준 역방향.

2. Models.py 설계

  • models.ForeignKey(to, on_delete, **options) :

    • to : 참조할 class의 이름
    • on_delete : 참조하는 class가 삭제 될 경우, records의 삭제 처리방식 선택 (CASCADE,SET_NULL,NO ACTION,RESTRICT)
    • null = True : on_delete이 SET_NULL일 경우 필수

SET_NULL: Set the reference to NULL (requires the field to be nullable). For instance, when you delete a User, you might want to keep the comments he posted on blog posts, but say it was posted by an anonymous (or deleted) user. SQL equivalent: SET NULL.

  • models.ManyToManyField(to, **options) :

    to : 참조할 클래스의 이름
    through = : many-to-many관계의 중간 테이블이 될 클래스 이름.

(More on this @https://docs.djangoproject.com/en/3.0/ref/models/fields/)

  • many-to-many의 클래스를 장고에게 맞기지 않고 직접 할 경우, Foreign Keys로만 이루어진 클래스를 생성.

  • 클래스이름은 many-to-many의 관계를 가진 두개의 클래스 이름의 조합으로 만든다.

  • Foreign Key의 변수 이름은 _id를 쓰지않는다. DB에 저장시, 장고가 알아서 붙여준다.

  • 한 클래스에서 아직 정의되지 않은 class의 primary key를 참조할때는, 참조하게 될 클래스 이름 앞뒤에 ' '를 넣으면 나중에 불러오게 할 수 있다.

  • 모델 설계가 끝나면 꼭 migrations 를 잊지말자!

3. settings.py 설정

  • my_settings.py 파일을 만들어 데이터베이스를 지정한다. my_settings는 프로젝트 최상위 디렉토리에 저장하도록 하자.

  • settings.py를 알맞게 설정한다.

@ settings.py
...
import my_settings
...

INSTALLED_APPS = [......
		  ......
                  ......
                  'drink'
                 ]
DATABASES = my_settings.DATABASES

4. Mysql 데이터베이스 생성

  • 가상환경에 mysqlclient가 설치 된 것을 확인하고 진행하자.
pip install mysqlclient
  • root로 로그인 하여 앞서 만든 데이터베이스를 확인하자
mysql -u root -p
Enter password:

mysql> show databases;
mysql> create database starbucks character set utf8mb4 collate utf8mb4_general_ci;
mysql> use starbucks;
mysql> show tables;
+---------------------+
| Tables_in_starbucks |
+---------------------+
| allergies           |
| categories          |
| django_content_type |
| django_migrations   |
| django_session      |
| drink_allergies     |
| drinks              |
| sub_categories      |
+---------------------+

5. 데이터 입력

전체코드

python manage.py shell

### 카테고리/음료카테고리/음료의 레코드 추가
>>> from drink.models import *
>>> Category.objects.create(name="음료")
<Category: Category object (1)>
>>> SubCategory.objects.create(name="cold brew", category=Category.objects.get(id=1))
<SubCategory: SubCategory object (1)>
>>> Drink.objects.create(name_en="dolce cold brew", name_kr="돌체콜드브루", description="무더운 여름철,....", thumbnail="www.www.kr/jpeg", allergy="우유", serving=300.1, calories=300.4, saturated_fat=12.3, protein=30.4, sodium=3.4, sugar=100.2, caffeine=5, category=Category.objects.get(id=1), sub_category=SubCategory.objects.get(id=1))
<Drink: Drink object (1)>
>>> Drink.objects.create(name_en="cold brew", name_kr="콜드브루", description=" 무더운 여름철,....", thumbnail="www.www.kr/jpeg", allergy="우유", serving=300.1, calories=300.4, saturated_fat=12.3, protein=30.4, sodium=3.4, sugar=100.2, caffeine=5, category=Category.objects.get(id=1), sub_category=SubCategory.objects.get(id=1))
<Drink: Drink object (2)>

# 생성한 음료의 필드에 접근
>>> drink_1 = Drink.objects.get(id=1)
>>> drink_1
<Drink: Drink object (1)>
>>> drink_1.category
<Category: Category object (1)>
>>> drink_1.category_id
1

### select_related 사용하기
>>> SubCategory.objects.filter(id=drink_1.category_id)
<QuerySet [<SubCategory: SubCategory object (1)>]>
>>> SubCategory.objects.filter(id=drink_1.category_id).values
<bound method QuerySet.values of <QuerySet [<SubCategory: SubCategory object (1)>]>>
>>> SubCategory.objects.filter(id=drink_1.category_id)[0]
<SubCategory: SubCategory object (1)>
>>> SubCategory.objects.filter(id=drink_1.category_id)[0].name
'cold brew'
>>> drink_2 = Drink.objects.select_related('category').get(id=1)
>>> drink_2
<Drink: Drink object (1)>
>>> drink_2.category.name
'음료'

### prefetch_related 사용하기
>>> category = SubCategory.objects.get(id=1)
>>> category.drink_set.all()
<QuerySet [<Drink: Drink object (1)>, <Drink: Drink object (2)>]>

>>> SubCategory.objects.filter(id=1).prefetch_related("drink_set")
<QuerySet [<SubCategory: SubCategory object (1)>]>
>>> drink_3 = SubCategory.objects.filter(id=1).prefetch_related("drink_set")
>>> drink_3[0]
<SubCategory: SubCategory object (1)>
>>> drink_3[0].category
<Category: Category object (1)>

>>> drink_3[0].drink_set.filter(id=1)
<QuerySet [<Drink: Drink object (1)>]>
>>> drink_3[0].drink_set.get(id=1).name_kr
'돌체콜드브루'

many-to-many field에 데이터 기록하는법:

  • .add 사용하기:
drink1 = Drink.objects.get(id=2)           
allergy1 = Allergy.objects.get(name='soy')

drink1.allergy.add(allergy1)             #drink id=2에 allergy id=2(soy)가 더해진다
  • .create 사용하기:
drink1.allergy.create(name='pistaccio')
>>><Allergy: Allergy object(5)>        # allergies에 pistaccio가 더해진다.

결과는 DB에서 확인할 수 있다.

모든 필드 값 한번에 업데이트 하기

qs = Product.objects.all()
qs.update(is_in_stock=True)

복수 특정 필드 값 업데이트 하기

Address.objects.filter(id=1).update(postcode_id=1, users_id=1)
profile
🔰

0개의 댓글