환경
- python 3.9
- fastapi 0.73.0
- pydantic 1.9.0 (VO객체 validtion, json encode/decode 등에 관여하는 라이브러리로 보임)
이슈
- MySql에서 select한 datetime 컬럼을 별도의 형식 변환 없이 React client에 전달하고, React에서는 dayjs 를 사용하여 포맷팅/출력 해 주고 싶다.
- 현재는 api response에 타임존(timezone) 정보가 없기 때문에 국제화 출력이 불가한 상태
- 현재 DB의 timezone은 KST가 아닌 UTC라고 가정한다.
해결
- 기본적으로 VO객체들은 pydantic의 BaseModel을 상속(?)받는 구조로 되어 있다. 이 BaseModel을 상속받는 다른 타입 BaseModelDtm을 정의하고, 이 정의에는 timezone 관련 json encoder를 추가 정의한다.
- 이후 VO클래스는 BaseModel 대신 BaseModelDtm 을 사용하여 타입 정의를 한다.
소스
model.py
...
class BaseModelDtm(BaseModel):
class Config:
# pydantic 기본 셋팅에서 response 객체의 datetime 타입 필드가 ISO 8601 형식으로 json encode 되지 않는 문제가 있어서,
# 해당 필드들이 ISO 8601 형태로 json encode 될 수 있도록 설정을 추가한 클래스 생성
# 최초 config.py (Settings(BaseSettings) 클래스)에서 전역설정을 할 수 있기를 기대했으나 실패하여 이렇게 처리함.
json_encoders = {
# 이렇게 하니 timezone이 utc 라는 정보가 포함된다.
datetime: lambda dt: dt.replace(
microsecond=0, tzinfo=timezone.utc # 얘를 utc말고 kst 등으로 하는 방법은 아직 모르겠다.
).isoformat()
# 이렇게 하니 timezone 정보가 포함되지 않는다 (BaseModelDtm 생성 전과 동일)
# datetime: lambda dt: dt.isoformat()
}
...
# class TestVO(BaseModel):
class TestVO(BaseModelDtm):
id: Optional[str]
name: Optional[str]
create_time: Optional[datetime]
update_time: Optional[datetime]
...
참고