6편 — 마이그레이션 = "DB야, 나 바뀌었어"
🎬 지난 이야기
5편에서는 Django 모델이 실제로 무엇인지 살펴봤습니다. models.py에 클래스 하나를 쓰면, Django가 그것을 DB 테이블로 만들어준다고 했죠. 그런데 그 테이블, 한 번 만들면 끝일까요? 오늘은 "모델을 수정했더니 갑자기 사이트가 깨졌어요" 라는 상황에서 출발합니다.
모델을 고쳤는데 갑자기 이런 화면이 떴던 적 있으신가요?
OperationalError at /polls/
table polls_question has no column named 'author'
번역하면 "야, 테이블에 author 칸이 없는데?"입니다. 분명히 models.py에 author 필드를 추가했는데, 왜 DB는 그걸 모르는 걸까요?
🤖 AI가 짜준 코드
프롬프트: "Question 모델에 작성자 이름 필드 추가해줘"
AI가 models.py를 이렇게 수정해줬습니다.
# polls/models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
author = models.CharField(max_length=100, default='익명') # ← 새로 추가
그리고 터미널에서 이 두 줄을 치라고 했을 겁니다.
python manage.py makemigrations
python manage.py migrate
왜 두 번이나 칠까요? 하나로 합치면 안 될까요?
🔍 한 줄씩 통역
models.py를 고쳤다 = 설계도를 바꿨다
5편에서 모델은 "테이블 설계도"라고 했죠. 지금 한 일은 설계도에 author라는 새 칸을 펜으로 그려 넣은 것입니다. 문제는, 설계도를 바꿨다고 해서 이미 지어진 건물(DB)이 자동으로 바뀌지는 않는다는 겁니다.
Django는 설계도(models.py)와 실제 DB 사이에 "변경 명세서" 를 따로 만들어 관리합니다. 그게 바로 마이그레이션 파일입니다.
makemigrations — 변경 명세서 작성
python manage.py makemigrations
이 명령은 "지금 models.py가 이전이랑 뭐가 달라졌는지 비교해서, 변경 내용을 메모해둬"라는 뜻입니다.
실행하면 polls/migrations/ 폴더 안에 파일이 하나 생깁니다.
polls/migrations/0002_question_author.py
이 파일을 열어보면 사람이 읽을 수 있는 파이썬 코드로 "Question 테이블에 author 칼럼을 추가하라"는 지시가 담겨 있습니다. 일종의 공사 지시서입니다. 아직 공사는 시작 안 했어요.
migrate — 명세서대로 실제 DB 공사
python manage.py migrate
이 명령이 공사를 실제로 집행합니다. "명세서에 적힌 대로 DB를 바꿔줘"라는 뜻이죠.
실행하면 Django는 "내가 이 명세서를 이미 반영했나?" 를 내부 테이블(django_migrations)에서 확인하고, 아직 안 한 것만 골라서 실행합니다. 그래서 명세서가 쌓여도 migrate 한 번이면 됩니다.
왜 두 단계로 나눌까?
| 단계 | 비유 | 결과물 |
|---|---|---|
makemigrations |
건축 설계 변경 → 공사 지시서 발행 | .py 파일 생성 |
migrate |
지시서대로 건물 실제 공사 | DB 테이블 변경 |
분리한 이유가 있습니다. 지시서를 Git에 저장해두면 팀원 누구나 같은 DB 상태를 재현할 수 있거든요. 공사 이력이 파일로 남는 셈입니다.
⚠️ 자주 깨지는 지점
① makemigrations는 했는데 migrate를 빠뜨린 경우
OperationalError: table polls_question has no column named 'author'
지시서만 써놓고 공사를 안 한 상태입니다. python manage.py migrate 를 추가로 실행하세요.
② default 값 없이 NOT NULL 필드를 추가한 경우
author = models.CharField(max_length=100) # default 없음
It is impossible to add a non-nullable field 'author' without specifying a default.
기존에 이미 쌓인 행들은 author 값이 뭔지 모르니까 Django가 멈춰서 물어보는 겁니다. 해결책은 두 가지입니다.
default='익명'처럼 기본값을 지정하거나,null=True, blank=True를 붙여 "비어도 돼"라고 허용하세요.
🎮 직접 해보기
미션: 지금 여러분의 Question 모델에 author 필드를 추가하고, 마이그레이션 두 단계를 직접 실행해보세요. 그리고 Django 관리자 페이지(/admin/)에 접속해서 Question을 하나 추가할 때 author 입력칸이 생겼는지 확인해보세요!
author = models.CharField(max_length=100, default='익명')
실행 후 polls/migrations/ 폴더에 0002_... 파일이 생겼다면 성공입니다. 파일이 안 생기거나 에러가 났다면 테크창 Q&A 게시판에 에러 메시지를 그대로 붙여넣어 질문해주세요! 같이 해결해드립니다.
⏭️ 다음 편 예고
모델도 만들었고, DB도 바꿨는데 — 그 데이터를 화면에서 받아서 저장하려면 어떻게 해야 할까요? 다음 편에서는 <form> 태그와 Django가 만나는 순간, 즉 "사용자 입력을 DB에 꽂는 법"을 통역해드립니다.
📚 시리즈: AI가 짜준 Django, 이제 알고 씁니다 · 6편 (총 9편 중)
테크창 연구팀 | 인천대학교 창의인재개발학과 전공심화연구모임
본 칼럼은 AI 보조로 작성되었으며, 코드·예시는 학습용입니다.
댓글 (0)
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요!