2022. 1. 4. 16:07ㆍ강의 정리/Django Models
↑관계형 데이터베이스 (mariaDB)에 대해서 자세히 알고싶다면???
https://blog.naver.com/yardyard/222555167886
-MYSQL에서 DATABASE를 표현하는 다른 말로, 스키마라는 표현을 사용함.
Migrations란?
모델의 변경내역을 "데이터베이스 스키마"로 반영시키는 효율적인 방법을 제공
# Migrations을 통해서 우리는 모델만 개발하고 데이터베이스에 자동으로 반영시킬 수 있다.
관련 명령
- 마이그레이션 파일 생성 # 순서 1
>>> python manage.py makemigrations <앱이름>
- 지정 데이터베이스에 마이그레이션 적용 # 순서 3
>>> python manage.py migrate <앱이름>
- 마이그레이션 적용 현황 출력 # 중간 중간 틈틈히
>>> python manage.py showmigrations <앱이름>
출력된 코드
C:\Users\yardy\Desktop\DjangoPractice\dongbaek>python manage.py showmigrations
accounts
[X] 0001_initial
[X] 0002_alter_profile_user
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
[X] 0012_alter_user_first_name_max_length
church
(no migrations)
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
inflearn
[X] 0001_initial
instagram
[X] 0001_initial
[X] 0002_post_is_public
[X] 0003_post_photo
[X] 0004_auto_20211231_1531
[X] 0005_auto_20211231_1722
[X] 0006_auto_20220103_1516
sessions
[X] 0001_initial
- 지정 마이그레이션의 SQL 내역 출력 # 순서 2
>>> python manage.py sqlmigrate <앱이름> <마이그레이션-이름>
- 장고의 전체 기본 앱들에 대해서 마이그레이션 수행
>>>python manage.py migrate
Migrations 파일
데이터베이스에 어떤 변화를 가하는 Operation들을 나열
- 기본 Operation : 테이블 생성 / 삭제, 필드 추가 / 삭제 등
- 커스텀 Operation : 파이썬 / SQL Operation # ex)데이터 마이그레이션 등 Migration에 커스텀 과정을 넣을 수 있다.
대개 모델로부터 자동 생성 -> makemigrations 명령
- 모델 참조없이 빈 마이그레이션 파일 만들어서 직접 채워넣기도 함.
주의) 같은 Migration 파일이라 할지라도, DB종류에 따라 다른 SQL이 생성됩니다.
- 모든 데이터베이스 엔진들이 같은 기능을 제공하지는 않는다.
- ex) SQLite DB에서는 기존 테이블에 컬럼 추가가 지원되지 않음.
ex) dongbaek/accounts/migrations/0001_initial.py
# Generated by Django 3.2.10 on 2022-01-03 04:50
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('address', models.CharField(max_length=100)),
('zipcode', models.CharField(max_length=6)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
Migrations 파일 생성 및 적용 과정
0. 앱/models.py
- 모델 변경 # makemigrations 명령
1. 마이그레이션 파일들 생성
- 필히, 생성된 마이그레이션 파일 내역 확인 + sqlmigrate 명령으로 SQL 확인
- 즉 나의 의도에 맞게 생성이 되었는지 확인
2. 데이터베이스 서버
- migrate 명령으로 DB에 적용
언제 makemigrations를 하는 가?
모델 필드 관련된 어떠한 변경이라도 발생 시에 마이그레이션 파일 생성
- 실제로 DB Shceme에 가해지는 변화가 없더라도 수행
마이그레이션 파일은 모델의 변경내역을 누적하는 역할
- 적용된 마이그레이션 파일은 절대 삭제하면 안됨
- 마이그레이션 파일이 너무 많아질 경우, squashmigrations 명령으로 다수의 마이그레이션 파일을 통합할 수 있다.
마이그레이션 Migrate ( 정 / 역 방향 )
정방향 (1->2->3->4->5)
역방향(5->4->3->2->1)
python manage.py migrate <앱이름>
- 미적용 <마이그레이션-파일>부터 <최근-마이그레이션-파일>까지 정방향으로 순차적으로 수행
python manage.py migrate <앱이름> <마이그레이션-이름>
- 지정된 <마이그레이션-이름>이 현재 적용된 마이그레이션보다
- 이후라면, 정방향으로 순차적으로 지정된 마이그레이션까지 정방향 수행
- 이전이라면, 역방향으로 순차적으로 지정 마이그레이션 이전까지 역방향 수행
즉 현재의 migration 위치를 파악하는게 중요~!!!! # showmigrations 명령
ex) 1~7번까지의 migration 파일이 있을 때 현재가 5번 파일인데 3번 파일을 지정하면 5번 취소, 4번 취소, 하여 역방향으로 3번으로 가게 됨
코드로 설명하면
>>> python manage.py migrate <app> 0003_a.py
0007_a.py
0006_a.py
0005_a.py (현재 위치) ↓ 지정된 위치로 역방향 이동
0004_a.py ↓
0003_a.py (지정된 위치)
0002_a.py
0001_a.py
ex) 정방향 예시로 아래 코드를 예로 들면
>>> python manage.py migrate <app> 0005_a.py
0007_a.py
0006_a.py
0005_a.py (지정된 위치) 지정된 위치로 정방향 이동
0004_a.py ↑
0003_a.py (현재 위치) ↑
0002_a.py
0001_a.py
마이그레이션 이름 지정
전체 이름(파일명)을 지정하지 않더라도, 1개를 판별할 수 있는 일부만 지정해도 OK
migrations/000_1_initial.py
migrations/000_2_created_field.py
migrations/000_2_update_field.py
Shell
>>> 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 # 앱의 모든 마이그레이션을 rollback
새로운 필드가 필수필드라면?
필수필드 여부 : blank / null 옵션이 모두 False 일 때 (디폴트)
makemigrations 명령을 수행할 때, 기존 Record들에 어떤 값을 채워넣을 지 묻습니다.
- 지금 그 값을 입력하겠다. # 반드시 필드 타입에 맞게 값을 채워넣어야 한다.
- 명령 수행을 중단
C:\Users\yardy\Desktop\DjangoPractice\dongbaek>python manage.py makemigrations inflearn
You are trying to add a non-nullable field 'author' to post without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> 1
Migrations for 'inflearn':
inflearn\migrations\0002_post_author.py
- Add field author to post
# dongbaek/inflearn/models.py
from django.conf import settings
from django.db import models
from django.conf import settings
from django.db.models.deletion import CASCADE
# Create your models here.
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE, related_name="inflearn_author_set")
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
협업 Tip
절대 하지 말아야 할 일
- 팀원 각자가 마이그레이션 파일을 생성 -> 충돌 발생
추천 ) 마이그레이션 파일 생성은 1명이 전담해서 생성
- 생성한 마이그레이션 파일을 버전관리에 넣고, 다른 팀원들은 이를 받아서 migrate만 수행
개발 시에 "서버에 아직 반영하지 않은" 마이그레이션을 다수 생성했었다면?
- 이를 그래도 서버에 반영 ( migrate ) 하지말고,
- 하나의 마이그레이션으로 합쳐서 적용하기를 권장
방법 1) 서버로의 미적용 마이그레이션들을 모두 롤백 -> 롤백된 마이그레이션들을 모두 제거 -> 새로이 마이그레이션 파일 생성
방법 2) 미적용 마이그레이션들을 하나로 합치기 -> squashmigrations 명령
'강의 정리 > Django Models' 카테고리의 다른 글
Django의 모델에 대해서 (0) | 2022.01.05 |
---|---|
관계를 표현하는 모델 필드 #OneToOneField (0) | 2022.01.03 |
관계를 표현하는 모델 필드 #ForeignKey (0) | 2021.12.31 |
Django-debug-toolbar를 통한 SQL 디버깅 (0) | 2021.12.30 |
동백 // QuerySet에 정렬 조건 추가 (0) | 2021.12.30 |