반응형
발생
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) → 더 안전하고 명확함
반응형