Django를 사용해 데이터를 관리하다 보면, 데이터베이스에 샘플 데이터를 로드하기 위해 'Fixtures'를 사용하게 됩니다. 하지만 외래 키(Primary Key, Foreign Key) ID를 하드코딩하면 데이터베이스 간 데이터 이동 시 문제가 발생하거나 ID가 변경될 경우 Fixtures가 깨질 위험이 있습니다. 이를 해결하기 위해 Django는 '자연 키(Natural Key)'라는 기능을 제공합니다.
왜 하드코딩된 ID를 피해야 할까?
- 데이터 불일치 문제: 서로 다른 데이터베이스 간 데이터가 불일치할 가능성이 높아집니다.
- 유지보수 어려움: ID 변경 시 Fixtures를 수정해야 하는 번거로움이 생깁니다.
- 수작업의 증가: 관계를 수동으로 관리하는 데 시간과 노력이 더 많이 소요됩니다.
자연 키란?
자연 키는 숫자 ID 대신 의미 있는 값을 사용하여 외래 키 관계를 참조할 수 있도록 합니다. 예를 들어, 카테고리를 참조할 때 숫자 ID(예: 1) 대신 카테고리 이름(예: 'Electronics')을 사용하는 방식입니다.
자연 키 설정하기
1단계: 모델에 자연 키 정의하기
먼저, 외래 키로 참조되는 모델에 natural_key()
메서드를 추가합니다.
from django.db import models
class CategoryManager(models.Manager):
def get_by_natural_key(self, name):
return self.get(name=name)
class Category(models.Model):
name = models.CharField(max_length=255, unique=True)
objects = CategoryManager()
def natural_key(self):
return (self.name,)
위 코드에서는 카테고리를 이름으로 참조하도록 설정했습니다.
2단계: 자연 키를 활용한 Fixtures 작성하기
자연 키를 활용하면 Fixtures에서 숫자 ID 대신 의미 있는 값을 사용할 수 있습니다.
기존 방식 (숫자 ID 사용)
[
{
"model": "shop.category",
"pk": 1,
"fields": {
"name": "Electronics"
}
},
{
"model": "shop.product",
"fields": {
"name": "Smartphone",
"category": 1
}
}
]
개선된 방식 (자연 키 사용)
[
{
"model": "shop.category",
"fields": {
"name": "Electronics"
}
},
{
"model": "shop.product",
"fields": {
"name": "Smartphone",
"category": ["Electronics"]
}
}
]
위와 같이 작성하면 Django가 자동으로 이름을 참조하여 외래 키를 매핑합니다.
3단계: Fixtures 로드하기
Fixtures를 작성한 후, 다음 명령어로 데이터를 로드할 수 있습니다.
bash
python manage.py loaddata your_fixture.json
Django는 get_by_natural_key()
메서드를 사용하여 외래 키를 동적으로 조회합니다.
자연 키를 언제 사용할까?
자연 키를 사용하는 경우
- 데이터베이스 간 호환성을 유지해야 하는 경우
- 모델에 고유한 필드(예: 이름, 슬러그, 사용자 이름)가 있는 경우
- 숫자 ID를 수동으로 관리하고 싶지 않은 경우
숫자 ID를 사용하는 경우
- 모델에 고유한 자연 식별자가 없는 경우
- 데이터셋이 작고 변경 가능성이 적은 경우
결론
Django에서 자연 키를 활용하면 데이터 관리가 훨씬 유연하고 간편해집니다. 숫자 ID에 의존하지 않고도 Fixtures를 유지보수할 수 있어, 특히 대규모 프로젝트에서 유용합니다. 만약 Django 프로젝트에서 Fixtures 사용으로 골머리를 앓고 있다면, 자연 키를 도입해 보세요. 더 이상 깨진 관계 때문에 스트레스받지 않아도 됩니다!