장고 django.db.utils.IntegrityError (Duplicate entry) 해결하기
문제 상황: 카카오 로그인 중 만난 고질적인 IntegrityError
내가 만든 서비스에서 카카오 소셜 로그인 기능을 넣었더니 다음과 같은 에러가 떴다:
django.db.utils.IntegrityError: (1062, "Duplicate entry '' for key 'accounts_customuser.email'")
이 에러는 데이터베이스에서 유니크 제약 조건에 위배되는 중복 키 에러로, 공백값과 관련된 문제가 있었기에 조금 더 깊이 파고들어야 했다.
문제 분석: 공백 이메일로 인한 중복
카카오 로그인을 통해 처음 가입하는 일부 사용자는 이메일 정보를 제공하지 않는 경우가 있었다. 이로 인해 다음과 같은 문제가 발생했다:
- 새로 가입하는 사용자들은 이메일 필드가 공백('')으로 설정되었다.
- 이후 동일한 조건의 다른 사용자들이 로그인할 때, 공백 값이 중복되면서 유니크 제약 조건에 걸려 IntegrityError가 발생했다.
즉, 소셜 로그인 사용자의 이메일이 공백일 경우 중복 문제가 발생하여 에러가 발생한 것이다.
해결 방법: 모델 필드의 유연성 확보
이 문제를 해결하기 위해 email 필드의 속성을 다음과 같이 변경했다:
email = models.EmailField(max_length=255, unique=True, blank=True, null=True)
이 설정은 다음과 같은 역할을 한다:
- unique=True: 여전히 이메일 필드는 유니크해야 한다.
- blank=True: 폼에서 공백 값을 허용한다.
- null=True: 데이터베이스에서 해당 필드 값이 NULL을 가질 수 있도록 한다.
이제 소셜 로그인 사용자들이 이메일을 제공하지 않아도 NULL이나 빈 값('')이 중복되어 유니크 제약 조건에 걸리는 문제를 방지할 수 있다.
추가 고려 사항 및 최적화
- 유효성 검사: 소셜 로그인 과정에서 이메일을 제공하지 않은 사용자들에게 가입 후 이메일을 입력하게끔 유도하는 프로세스를 추가할 수 있다.
- 데이터베이스 마이그레이션: 필드 변경 후 반드시 마이그레이션을 통해 데이터베이스 구조를 반영해야 한다.
python manage.py makemigrations
python manage.py migrate
결론
소셜 로그인과 같은 외부 연동은 종종 예기치 않은 데이터 처리 문제를 야기한다. 이번 사례처럼 공백이나 NULL 값으로 인해 유니크 제약 조건이 위반될 수 있는 경우, 필드 속성을 유연하게 조정하여 문제를 해결할 수 있다. 앞으로도 이러한 상황에 대비해 설계 단에서부터 다양한 시나리오를 고려하는 것이 중요하다.