[python] data.dict() vs jsonable_encoder(). 그리고 datetime 쿼리 삽질기

2025. 5. 26. 20:00·개발 일상

문제 상황

MongoDB에 저장된 데이터를 기간별로 가공해서 출력해주는 코드를 만들다가 이상한 점을 하나 발견했다.
createdAt 같은 날짜/시간 필드가 문자열(string)로 저장돼 있던 것.

처음엔 model에서 datetime으로 지정했으니까 당연히 datetime으로 들어갔을 거라 생각했는데, 막상 DB를 까보니까 "2024-01-01T12:00:00"처럼 string으로 저장되어 있던 것을 깨달았다.

그래서 코드 전체를 훑기 시작했다.
DTO, Model엔 분명히 datetime 타입으로 잘 들어가 있었고, 이상 없어 보였다.
그런데 문제는 라우터 코드였다.

라우터에서 데이터를 서비스 쪽으로 넘기기 전에 jsonable_encoder(data)로 한번 감싸고 있었는데, 이게 문제의 시작이었다.
jsonable_encoder는 datetime 객체를 자동으로 문자열로 변환해서 JSON 직렬화가 가능한 형태로 만들어준다. API 응답을 줄 땐 아주 편한 기능인데, 문제는 그걸 DB에 저장할 때도 써버리면 datetime이 문자열로 저장된다는 것을 알았다.

이걸 모르고 있다가, 나중에 날짜 필터 쿼리를 날릴 때 원하는 데이터가 하나도 안 나와서 한참 헤맸다. string으로 저장돼 있으니 당연히 {"$gte": datetime(...)} 같은 쿼리는 안 먹히는 거다.

정리한 결론

  • DB에 저장하거나 업데이트할 때는 data.dict()를 써야 한다. 그래야 datetime도 제대로 들어간다.
  • API 응답으로 데이터를 보낼 때는 jsonable_encoder()를 쓰는 게 맞다. 이때는 프론트엔드가 받아들이기 쉬운 형식이 필요하니까.

예시로 코드 정리하면 이렇다

# 저장할 때 (Create, Update)
data_to_save = data.dict()    # 전달받은 인자 형태를 잘 유지해서 dict로 담기
collection.insert_one(data_to_save) # 또는 서비스 코드로 전달

# 응답할 때 (Read)
result = collection.find_one({...})
return jsonable_encoder(result) # jsonable_encoder로 감싸서 전달(프론트에서 처리하기 수월하게 ~)

마무리

이번 경험으로 확실히 느낀 건, 무심코 쓴 인코더(jsonable_encoder) 하나가 데이터 전체 흐름을 엉망으로 만들 수 있다는 거다. FastAPI 쓸 때는 내부에서 쓸 데이터와 응답용 데이터를 명확히 구분해서 처리하는 습관을 들여야겠다.
그리고 무엇보다, 평소에 DB를 자주 까보는 습관이 얼마나 중요한지도 다시 깨달았다.

저작자표시 (새창열림)

'개발 일상' 카테고리의 다른 글

YOLO 객체 감지 후 위험 영역 판단 로직 개선기  (1) 2025.06.10
대량의 파일, 효율적으로 압축 & 전송하기 – 우분투 기반 백업 최적화  (2) 2025.06.02
MongoDB Aggregation을 활용한 통계 API 구현(python)  (1) 2025.05.22
주기적인 MongoDB 서비스 Down 증상 해결  (0) 2025.05.19
[React.js] setTimeout 사용 시 최신 상태(state)가 반영되지 않는 이슈 처리  (0) 2025.04.07
'개발 일상' 카테고리의 다른 글
  • YOLO 객체 감지 후 위험 영역 판단 로직 개선기
  • 대량의 파일, 효율적으로 압축 & 전송하기 – 우분투 기반 백업 최적화
  • MongoDB Aggregation을 활용한 통계 API 구현(python)
  • 주기적인 MongoDB 서비스 Down 증상 해결
레실이
레실이
  • 레실이
    레실이의 티스토리
    레실이
  • 전체
    오늘
    어제
    • 분류 전체보기 (91)
      • SE Bootcamp 내용 정리 (63)
      • 알고리즘 연습 (7)
      • Project 주저리 (4)
      • 기술 면접 source (3)
      • 개발 일상 (12)
      • 생성 AI 활용 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Linux
    CSR
    JavaScript
    문자열
    CORS
    ORM
    자료구조
    JS
    promise
    MVC
    비동기
    useState
    node.js
    useRef
    fastapi
    node
    state
    알고리즘
    인증/보안
    Ajax
    mongoDB
    Python
    객체
    IT
    react
    PickAndDrink
    데이터베이스
    ubuntu
    CSS
    DOM
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
레실이
[python] data.dict() vs jsonable_encoder(). 그리고 datetime 쿼리 삽질기
상단으로

티스토리툴바