[Django] 장고 Models를 활용한 데이터베이스 처리 - 4

Update:     Updated:

카테고리:

태그:

관계를 표현하는 모델 필드 (ManyToManyField)

ManyToManyField

M : N 관계에서 어느 쪽이라도 필드 지정 가능

ManyToManyField(to, blank=False)

# 방법 1)
class Post(models.Model):
    tag_set = models.ManyToManyField('Tag', blank=True)

class Article(models.Model):
    tag_set = models.ManyToManyField('Tag', blank=True)

class Tag(models.Model):
    name = models.CharField(max_length=100, unique=True)

# 방법 2)
class Post(models.Model):
    # ...

class Article(models.Model):
    # ...

class Tag(models.Model):
    name = models.CharField(max_length=100, unique=True)
    post_set = models.ManyToManyField('Post', blank=True)
    article_set = models.ManyToManyField('Article', blank=True)

RDBMS지만, DB따라 NoSQL기능도 지원

  • ex) 하나의 Post 안에 다수의 댓글 저장 가능

djkoch/jsonfield

  • 대게의 DB엔진에서 사용 가능
  • TextField/CharField를 래핑
  • dict 등의 타입에 대한 저장을 직렬화하여 문자열로 저장
    – 내부 필드에 대해 쿼리 불가

django.contrib.postgres.fields.JSONField

  • 내부적으로 PostgreSQL의 jsonb 타입
  • 내부 필드에 대해 쿼리 지원

adadchainz/django-mysql

  • MySQL 5.7 이상에서 json 필드 지원

마이그레이션을 통한 데이터베이스 스키마 관리 - 1

Mirgrations

모델의 변경내역을 “데이터베이스 스키마”로 반영시키는 효율적인 방법을 제공

관련 명령

  • 마이그레이션 파일 생성
    >> python manage.py makemigrations <앱이름>
    
  • 지정 마이그레이션의 SQL 내역 출력
    >> python manage.py sqlmigrate <앱이름> <마이그레이션-이름>
    
  • 지정 데이터베이스에 마이그레이션 적용
    >> python manage.py migrate <앱이름>
    
  • 마이그레이션 적용 현황 출력
    python manage.py showmigrations <앱이름>
    

Migration 파일

데이터베이스에 어떤 변화를 가하는 Operation들을 나열

  • 테이블 생성/삭제, 필드 추가/삭제 등
  • 커스텀 파이썬/SQL Operation
    – 데이터 마이그레이션 등

대개 모델로부터 자동 생성 -> makemigrations 명령

  • 모델 참조없이 빈 마이그레이션 파일 만들어서 직접 채워넣기도,

주의) 같은 Migration 파일이라 할지라도, DB종류에 따라 다른 SQL이 생성된다.

  • 모든 데이터베이스 엔진들이 같은 기능을 제공하진 않는다.
  • 예) SQLite DB에서는 기존 테이블에 컬럼 추가가 지원되지 않는다.

마이그레이션 파일 생성 및 적용

image

언제 makemigrations를 하는가?

모델 필드 관련된 어떠한 변경이라도 발생 시에 마이그레이션 파일 생성

  • 실제로 DB Scheme에 가해지는 변화가 없더라도 수행

마이그레이션 파일은 모델의 변경내역을 누적하는 역할

  • 적용된 마이그레이션 파일을 절대 삭제하면 안된다.
  • 마이그레이션 파일이 너무 많을 경우, squashmigrations 명령으로 다수의 마이그레이션 파일을 통합할 수 있다.

마이그레이션 Migrate (정/역 방향)

python manage.py migrate <앱이름>

  • 미적용 <마이그레이션-파일>부터 <최근-마이그레이션-파일>까지 `정방향으로 순차적으로` 수행

python manage.py migrate <앱이름> <마이그레이션-이름>

  • 지정된 <마이그레이션-이름>이 현재 적용된 마이그레이션보다 -- 이후라면, 정방향으로 순차적으로 지정 마이그레이션 forward 수행 -- 이전이라면, 역방향으로 순차적으로 지정 마이그레이션 backward 수행

마이그레이션 이름 지정

  • 전체 이름(파일명)을 지정하지 않더라도, 1개를 판별할 수 있는 일부만 지정해도 OK

shop/migrations/0001_initial.py shop/migrations/0002_create_field.py
shop/migrations/0002_update_field.py

>> python manage.py migrate blog 000 # FAIL (3개 파일에 매칭)  
>> python manage.py migrate blog 100 # FAIL (매칭되는 파일이 없음)  
>> python manage.py migrate blog 0001 # OK  
>> python manage.py migrate blog 0002 # FAIL (2개 파일에 매칭)  
>> python manage.py migrate blog 0002_c # OK  
>> python manage.py migrate blog 0002_create # OK  
>> python manage.py migrate blog 0002_update # OK  
>> python manage.py migrate blog zero # shop앱의 모든 마이그레이션을 rollback  

마이그레이션 순서는 파일명으로 정렬순?

from django.db import migrations, models

class Migration(migrations.Migration):
    dependencied = [
        ('shop', '0001_initial'),
    ]
    operations = [
        ...
    ]

id 필드가 생기는 이유

모든 DB 테이블에는 각 Row의 식별기준인 “기본키(Primary Key)”가 필요

  • 장고에서는 기본키로서 id(AutoField) 필드를 디폴트 생성
  • 다른 필드를 기본키로 지정하고 싶다면 primary_key=True 옵션 적용

마이그레이션을 통한 데이터베이스 스키마 관리 - 2

새로운 필드가 필수필드라면?

필수필드 여부 : blank/null 옵션이 모두 False 일 때 (디폴트)

makemigrations 명령을 수행할 때, 기존 Record들에 어떤 값을 채워넣을 지 묻는다.

  • 선택1) 지금 그 값을 입력하겠다.
  • 선택2) 명령 수행을 중단.

협업 Tip

절대 하지 말아야할 일

  • 팀원 각자가 마이그레이션 파일을 생성 -> 충돌 발생

추천) 마이그레이션 파일 생성은 1명이 전담해서 생성

  • 생성한 마이그레이션 파일을 버전관리에 넣고, 다른 팀원들은 이를 받아서 migrate만 수행

Tip

개발 시에 “서버에 아직 반영하지 않은” 마이그레이션을 다수 생성했다면?

  • 이를 그대로 서버에 Migrate 하지 말고, 하나의 Migration 으로 합쳐서 적용하기를 권장
    – 방법1) 서버로의 미적용 마이그레이션들을 모두 롤백하고 -> 롤백된 마이그레이션들을 모두 제거하고 -> 새로이 마이그레이션 파일을 생성
    – 방법2) 미적용 마이그레이션들을 하나로 합치기 -> squashmigrations 명령



🐢 현재 공부하고 있는 파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 - 이진석 강사 의 강의를 학습하며 기록 및 정리를 하기위한 내용들입니다. 🐢

감사합니다.😊

Django 카테고리 내 다른 글 보러가기

댓글남기기