본문 바로가기

UUID 잘 넣었는데 왜 조회가 안돼요?

@Jeeqong 2025. 3. 27. 21:30
반응형

발생

FastAPI 프로젝트에서 유저 정보를 업데이트할 때,

요청한 user_id와 조회된 user.id가 서로 다른 값으로 나왔다.

id: 0a0884cb-052a-4a07-98ea-ce21539e322c, <class 'uuid.UUID'>
👉🏻id: 0d13fcf3-4c31-4559-937c-cd3f5cb8e379, <class 'uuid.UUID'>

엥? 왜...?


디버깅 과정 요약

  • ✅ 직전에 id 타입을 varchar 에서 uuid 로 바꿨지...
  • 그게 문제인줄 알았지...
  • router, crud, service 파라메터 변수 다 확인하고 바꾸고 
  • ✅ UUID 타입은 uuid.UUID로 선언해두었고 모델에서도 잘 적용됨.
  • ✅ 엑셀로 업로드한 데이터도 이중으로 발생되던거 삭제하고 모델 생성으로 바꿔서
  • uuid.UUID 타입으로 저장되는거 확인함.
  • 데이터 삭제하고 엑셀 3번쯤 올려서 테스트해보고
  • ❌ 하지만 get_user_by_id 함수에서 계속 이상한 값이 반환됨.

원인 : .filter(OR) 조건

# 문제 코드
user = (
    db.query(User)
    .filter((User.deleted_at.is_(None)) | (User.id == user_id))
    .first()
)

문제 포인트: OR 조건으로 인해 deleted_at IS NULL인 첫 번째 유저가 조회됨.

→ 즉, user_id는 무시되고 다른 행이 걸릴 수 있음!!


해결 방법

# 정상적인 조회 방식
user = (
    db.query(User)
    .filter(User.id == user_id, User.deleted_at.is_(None))
    .first()
)
  • AND 조건으로 정확한 user_id 매칭
  • soft delete 된 row는 제외

깨닳은 바

UUID UUID는 uuid.UUID 타입을 정확히 써야 한다
.filter .filter(OR)는 조심해서 써야 한다 (first()와 함께 쓰면 특히 위험)
엑셀 업로드 문자열로 저장될 수 있어 타입 강제 변환 필요
디버깅 팁 print(type(value))로 타입을 꼭 확인하자

마무리

데이터타입은 신중하게 바꾸자.

오타보다 더 수치사 할거같은데 그리도 기록용으로 남겨본다.

이건 진짜 한 번 겪고 나면 절대 못 잊는 삽질이다.

특히 ORM에서 조건 걸 때 OR 연산은 웬만하면 피하거나, filter() 안에 쓸 땐 매우 조심하자.

# 기억하자
.filter(A | B) → 예상과 다른 결과 가능성 높음
.filter(A, B) → 더 안전하고 명확함

반응형
Jeeqong
@Jeeqong :: JQVAULT

Jeeqong's vault : 정보/기록을 쌓아두는 공간 웹개발 포스팅 일상 리뷰를 기록하는 공간입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차