
🎉🚖 택시 회사 안건 끝! 이제 웹 프로젝트의 백엔드 실장이 되었어요! 🌐🔧 앗, 파이썬 장고에서 ORM을 사용하기가 어렵다구요? 😨 걱정하지 마세요! SQL과 비교하여 설명 드리겠습니다. 🤗✨ 저도 대학 졸업 후에 유지보수, 전산실, 빅데이터 인턴으로 일하면서 SQL을 업무에서 자주 활용했었어요. 😄🎓 이 경험이 도움이 되었으면 좋겠습니다! 💖 SQL을 사용했던 사람이 ORM 사용에도 익숙해지도록, SQL⚡ ️ORM 비교 가이드를 만들어 보았습니다!
Django ORM을 활용하여 데이터베이스 관계 설정하기 (관계와 마이그레이션 포함) 😊
Django ORM을 사용하면 파이썬 클래스를 사용하여 데이터베이스 테이블을 정의할 수 있습니다. 이렇게 정의된 클래스를 '모델'이라고 합니다. 아래는 간단한 Book 모델의 예시입니다.
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
publication_date = models.DateField()
이 모델은 title과 publication_date 두 개의 필드를 갖는 Book 테이블을 생성합니다.
장고에서는 ForeignKey, ManyToManyField, OneToOneField 등의 필드를 사용하여 다양한 데이터베이스 관계를 설정할 수 있습니다. 각 관계 설정의 장점과 사용 상황을 설명하겠습니다.
장고에서 1:N 관계는 ForeignKey 필드를 사용하여 표현됩니다. 이러한 관계는 한 객체가 여러 객체와 관계를 맺을 수 있을 때 사용됩니다.
장점:
사용 상황 예시:
한 작가(Author)가 여러 책(Book)을 쓸 수 있는 경우, Author와 Book 모델 사이에 1:N 관계를 설정할 수 있습니다.
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
장고에서 N:N 관계는 ManyToManyField 필드를 사용하여 표현됩니다. 이러한 관계는 여러 객체가 여러 객체와 관계를 맺을 때 사용됩니다.
장점:
사용 상황 예시:
학생(Student)과 과목(Subject)간에 N:N 관계가 있을 수 있습니다. 하나의 학생이 여러 과목을 수강할 수 있고, 하나의 과목은 여러 학생이 수강할 수 있습니다.
class Student(models.Model):
name = models.CharField(max_length=100)
class Subject(models.Model):
name = models.CharField(max_length=100)
students = models.ManyToManyField(Student)
장고에서 1:1 관계는 OneToOneField 필드를 사용하여 표현됩니다. 이러한 관계는 한 객체가 정확히 한 개의 다른 객체와 관계를 맺을 때 사용됩니다.
장점:
사용 상황 예시:
사용자(User)와 프로필(Profile) 간에 1:1 관계가 있을 수 있습니다. 각 사용자는 하나의 프로필을 가지며, 각 프로필은 한 명의 사용자와 연결되어야 합니다.
class User(models.Model):
name = models.CharField(max_length=100)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email = models.EmailField()
이처럼 장고에서는 다양한 관계를 설정할 수 있으며, 각 관계 설정은 공간 및 시간 효율성, 관계 정확도 보장 등 여러 장점을 제공하며, 적절한 사용 상황에 따라 선택하여 사용할 수 있습니다.
on_delete=models.CASCADE는 작가가 삭제되면 그 작가의 책도 함께 삭제되어야 함을 의미합니다.
3. 데이터베이스 마이그레이션 수행 🚀
Django에서는 변경된 모델을 데이터베이스 스키마에 반영하기 위해 '마이그레이션'이라는 메커니즘을 제공합니다. 마이그레이션 파일은 모델의 변경 사항을 저장하는 파이썬 파일입니다.
모델에 변경사항이 있을 때, 아래의 명령으로 새로운 마이그레이션 파일을 만들 수 있습니다.
```shell
python manage.py makemigrations
그리고 아래의 명령으로 마이그레이션을 데이터베이스에 적용할 수 있습니다.
python manage.py migrate
이렇게 Django의 ORM을 사용하면, SQL 쿼리 없이도 데이터베이스와 상호작용할 수 있습니다. 이는 개발을 상당히 편리하게 만들어줍니다! 😉
| 번호 | 설명 | SQL 예제 | Model Manager 예제 |
|---|---|---|---|
| 1 | 모든 인스턴스 쿼리 | SELECT * FROM model_name; | ModelName.objects.all() |
| 2 | 단일 객체 가져오기 | SELECT * FROM model_name WHERE condition LIMIT 1; | ModelName.objects.get(condition) |
| 3 | 여러 객체 필터 | SELECT * FROM model_name WHERE condition; | ModelName.objects.filter(condition) |
| 4 | 조건에 맞지 않는 객체 | SELECT * FROM model_name WHERE NOT condition; | ModelName.objects.exclude(condition) |
| 5 | 특정 필드 정렬 | SELECT * FROM model_name ORDER BY field_name; | ModelName.objects.order_by('field_name') |
| 6 | 특정 필드 값 쿼리 | SELECT field_name FROM model_name; | ModelName.objects.values('field_name') |
| 7 | 필드 값 리스트 쿼리 | SELECT field_name FROM model_name; | ModelName.objects.values_list('field_name') |
| 8 | 쿼리셋 결과 확인 | SELECT EXISTS (SELECT 1 FROM model_name WHERE condition LIMIT 1); | ModelName.objects.filter(condition).exists() |
| 9 | 객체 수 반환 | SELECT COUNT(*) FROM model_name; | ModelName.objects.count() |
| 10 | 새 객체 생성 및 저장 | INSERT INTO model_name (field1, field2, ...) VALUES (value1, value2, ...); | ModelName.objects.create(field1=value1, field2=value2, ...) |
| 11 | 여러 객체 생성 및 저장 | INSERT INTO model_name (field1, field2, ...) VALUES (value1_1, value1_2, ...), (value2_1, value2_2, ...), ...; | ModelName.objects.bulk_create([ModelName(field1=value1_1, field2=value1_2, ...), ModelName(field1=value2_1, field2=value2_2, ...)]) |
| 12 | 객체 값 업데이트 | UPDATE model_name SET field1=value1, field2=value2 WHERE condition; | ModelName.objects.filter(condition).update(field1=value1, field2=value2) |
| Django Field Type | SQL Field Type |
|---|---|
models.AutoField | INTEGER (AUTO_INCREMENT) |
models.BooleanField | BOOLEAN |
models.CharField | VARCHAR |
models.DateField | DATE |
models.DateTimeField | DATETIME |
models.DecimalField | DECIMAL |
models.EmailField | VARCHAR |
models.FileField | VARCHAR |
models.FloatField | FLOAT or REAL |
models.ImageField | VARCHAR |
models.IntegerField | INTEGER |
models.BigIntegerField | BIGINT |
models.PositiveIntegerField | INTEGER |
models.PositiveSmallIntegerField | SMALLINT |
models.SlugField | VARCHAR |
models.SmallIntegerField | SMALLINT |
models.TextField | TEXT |
models.TimeField | TIME |
models.URLField | VARCHAR |
models.ForeignKey | INTEGER or VARCHAR (depends on the related field) |
models.OneToOneField | INTEGER or VARCHAR (depends on the related field) |
models.ManyToManyField | Creates a separate association table |