📌 Django 모델과 ForeignKey, 그리고 마이그레이션 (최종 정리) 🧐
Django는 웹 애플리케이션 개발을 쉽게 해주는 강력한 프레임워크입니다. 그중에서도 모델(Model)은 데이터베이스와 상호작용하는 핵심 요소입니다. 오늘은 모델의 ForeignKey 필드와 마이그레이션 과정을 자세히 알아보겠습니다.
1. ForeignKey 란 무엇일까요? 🔗
- ForeignKey 의 개념
- 관계형 데이터베이스(RDBMS)에서 테이블 간의 관계를 정의하는 데 사용되는 필드입니다.
- 단순히 참조만 하는 것이 아니라, 테이블 간의 관계(Relationship)를 설정하는 것이 핵심입니다.
- '외래 키'라고도 불리며, 다른 테이블의 특정 레코드를 참조하는 역할을 합니다.
- 예시: 블로그 게시글(Post) 테이블이 작성자(Author) 테이블의 특정 작성자를 참조하는 경우.
- 관계형 데이터베이스(RDBMS)에서 테이블 간의 관계를 정의하는 데 사용되는 필드입니다.
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(Author, on_delete=models.CASCADE) # ForeignKey 사용
def __str__(self):
return self.title
- Django 모델에서 ForeignKey 사용 예시
author = models.ForeignKey(Author, on_delete=models.CASCADE):Post모델의author필드는Author모델의 특정 레코드를 참조하는 ForeignKey입니다.on_delete=models.CASCADE: 참조하는Author레코드가 삭제될 때, 해당Author를 참조하는 모든Post레코드를 함께 삭제합니다. (CASCADE외에 다양한 옵션이 존재합니다.)CASCADE: 연결된 모든 레코드 삭제PROTECT: 연결된 레코드가 있을 경우, 삭제 불가SET_NULL: 연결된 레코드가 삭제될 때, 외래 키를NULL로 설정SET_DEFAULT: 연결된 레코드가 삭제될 때, 외래 키를 기본값으로 설정DO_NOTHING: 연결된 레코드가 삭제되어도 아무런 조치 취하지 않음 (권장하지 않음)- 필요에 따라 적절한 옵션을 선택해야 합니다.
- RDBMS (관계형 데이터베이스) 란?
- 데이터를 테이블 형태로 저장하고, 테이블 간의 관계(Relationship)를 설정하여 데이터를 효율적으로 관리하는 데이터베이스 시스템입니다.
- 단순히 데이터를 저장하는 것뿐만 아니라, 데이터 간의 관계를 통해 좀 더 복잡하고 효율적인 데이터 관리가 가능합니다.
- MySQL, PostgreSQL, SQLite 등이 있습니다.
- 데이터를 테이블 형태로 저장하고, 테이블 간의 관계(Relationship)를 설정하여 데이터를 효율적으로 관리하는 데이터베이스 시스템입니다.
2. 마이그레이션 (Migration) 이란 무엇일까요? ⚙️
- 마이그레이션의 정의
- Django 모델을 변경했을 때, 변경 사항을 데이터베이스 스키마에 반영하는 과정입니다.
- 모델 변경은 코드 상의 변경이며, 데이터베이스에도 해당 변경 사항을 적용해야 합니다.
- Django는 모델 변경 사항을 마이그레이션 파일로 관리하며, 이를 통해 데이터베이스 스키마를 체계적으로 관리할 수 있습니다.
- 마이그레이션 파일은 일종의 데이터베이스 변경 이력이며, 이를 통해 언제든지 데이터베이스 스키마를 원하는 상태로 변경할 수 있습니다.
- Django 모델을 변경했을 때, 변경 사항을 데이터베이스 스키마에 반영하는 과정입니다.
- 마이그레이션 관련 주요 명령어
python manage.py makemigrations 앱이름/:- 앱 이름을 지정하는 이유: Django 프로젝트는 여러 앱으로 구성될 수 있습니다. 각 앱은 독립적인 기능을 수행하며, 데이터베이스 모델도 별도로 관리해야 합니다. 앱 이름을 지정함으로써, 특정 앱의 모델 변경 사항에 대한 마이그레이션 파일을 생성할 수 있습니다. 실수로 다른 앱의 모델을 건드리는 것을 방지하고, 마이그레이션 관리를 효율적으로 할 수 있습니다.
- 실수 방지:
makemigrations를 실행할 때 앱 이름을 지정하지 않으면, 모든 앱의 변경사항이 하나의 마이그레이션 파일에 포함될 수 있습니다. 이는 충돌과 오류를 유발할 수 있으므로 앱별로 관리하는 것이 필수적입니다. - 예시:
python manage.py makemigrations blog/(blog 앱에 대한 새로운 마이그레이션 파일 생성)
2. **`python manage.py migrate 앱이름/`:**
* `makemigrations`로 생성된 **마이그레이션 파일에 정의된 변경 사항을 실제 데이터베이스에 적용**하는 명령어입니다.
* 앱 이름을 지정하여 특정 앱의 마이그레이션만 적용하거나, 앱 이름을 생략하여 모든 앱의 마이그레이션을 적용할 수 있습니다.
* **앱별 관리:** `migrate` 역시 앱 이름을 지정하여 **각 앱의 마이그레이션을 독립적으로 적용**할 수 있습니다.
* **예시:** `python manage.py migrate blog/` (blog 앱에 대한 **마이그레이션 적용**)
- 데이터베이스 테이블:
- 마이그레이션을 적용하면, 데이터베이스에 모델에 해당하는 테이블과 관계가 생성됩니다.
- 테이블 이름은 기본적으로
앱이름_모델이름형식으로 생성됩니다. (예:blog_post,blog_author)
3. 마이그레이션 실수 대처법 🚨
- 마이그레이션 실수로 인한 문제점
- 데이터베이스 스키마가 원하지 않는 형태로 변경되어 오류가 발생할 수 있습니다.
- 데이터 손실 및 불일치의 위험이 있습니다.
- 마이그레이션 실수 대처 방법
- SQLite 데이터베이스 삭제는 최후의 수단! ❌:
- SQLite 데이터베이스를 삭제하고 다시 만들면, 기존 데이터가 모두 손실되므로 절대로 해서는 안 됩니다.
- 주의: 개발 환경에서는 SQLite를 사용하기도 하지만, 실제 서비스 환경에서는 다른 데이터베이스 시스템 (MySQL, PostgreSQL 등)을 사용하는 것이 일반적입니다.
- SQLite 데이터베이스를 삭제하고 다시 만들면, 기존 데이터가 모두 손실되므로 절대로 해서는 안 됩니다.
- SQLite 데이터베이스 삭제는 최후의 수단! ❌:
2. **이전 마이그레이션으로 되돌리기 (Rollback) ⏪:**
* 실수로 잘못된 마이그레이션을 적용했다면, **특정 마이그레이션 시점으로 데이터베이스를 되돌릴 수 있습니다**.
* **예시:** `0002` 마이그레이션 적용 후 `0003`을 적용했는데, `0003`에 문제가 있다면, `python manage.py migrate 앱이름/ 0002` 명령어를 실행하여 **`0002` 마이그레이션이 적용된 상태로 데이터베이스를 되돌릴 수 있습니다**.
* **주의:** 마이그레이션 되돌리기는 데이터 구조를 이전 상태로 돌리는 것이므로, **데이터 손실이 발생할 수 있습니다**.
* `0003` 파일 자체는 삭제되지 않고 그대로 남아있습니다. (마이그레이션 이력을 관리하기 위함)
4. 마이그레이션 파일 예시 📝
# 0001_initial.py (최초 마이그레이션)
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Author',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='Post',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('content', models.TextField()),
('author', models.ForeignKey(on_delete=models.CASCADE, to='blog.Author')),
],
),
]
5. 마무리 및 추가 정보 💡
- Django 모델의
ForeignKey는 RDBMS에서 테이블 간의 관계를 정의하고 관리하는 데 중요한 역할을 합니다.- 단순히 데이터를 참조하는 것 이상의 의미를 가지며, 데이터 무결성을 유지하는 데도 중요한 역할을 합니다.
- 마이그레이션은 데이터베이스 스키마를 안전하고 체계적으로 관리하는 데 필수적인 과정입니다.
- 마이그레이션 파일 관리는 데이터베이스 스키마를 일관성 있게 유지하고, 변경 사항을 추적하는 데 도움이 됩니다.
- 앱 이름을 지정하여 마이그레이션을 관리하는 것은 필수이며, 오류를 줄이고 개발 효율성을 높일 수 있습니다.
- 마이그레이션 실수 시, 이전 마이그레이션으로 되돌리는 방법을 사용하면 데이터 손실을 어느 정도 방지할 수 있지만, 데이터 손실 가능성을 항상 인지하고 있어야 합니다.
- 마이그레이션을 적용하기 전에는 반드시 백업을 하는 것이 중요합니다.
'Python > Django' 카테고리의 다른 글
| Django AUTH USER 사용자 모델 (2) | 2025.01.08 |
|---|---|
| Django 워크플로우 정리 (CRUD, 로그인 기능까지) (0) | 2025.01.08 |
| 다대다 관계 보충설명 (7) | 2025.01.08 |
| [TIL] ForeignKey 보충 (코드예시) (0) | 2025.01.08 |
| [TIL] 프레임워크에 대해 (3) | 2025.01.06 |