반응형
jsonable_encoder
데이터 자료형을 json compatiable한 데이터로 바꿔주는 함수이다.
다른 파이썬 라이브러리를 사용할때 json 호환 데이터를 요구할 경우가 있다면 이 함수를 이용하자
가령 예를들면 데이터베이스는 Pydantic model을 받지 않고 dict만 받는 경우가 있다.
또는 datetime을 데이터베이스로 넘겨줄때 str로 바꿔주어야 한다.
이럴때 jsonable_encoder를 사용한다.
아래는 그 예제이다.
from datetime import datetime
from typing import Optional
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
fake_db = {}
class Item(BaseModel):
title: str
timestamp: datetime
description: Optional[str] = None
app = FastAPI()
@app.put("/items/{id}")
def update_item(id: str, item: Item):
json_compatible_item_data = jsonable_encoder(item)
fake_db[id] = json_compatible_item_data
PUT operation
put은 데이터를 업데이트할 때 쓰이는 operation이다. PUT대신에 PATCH도 사용 가능하다.
from typing import List, Optional
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
price: Optional[float] = None
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
return items[item_id]
@app.put("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
update_item_encoded = jsonable_encoder(item)
items[item_id] = update_item_encoded
return update_item_encoded
반응형
exclude_unset
위 예제에서 주의해야 할 점이 있다.
아래와 같은 데이터를 보냈다고 하자.
{
"name": "Barz",
"price": 3,
"description": None,
}
나는 위 데이터만 업데이트 하고싶다고 치자.
허나 Pydantic model에 초기값이 tax로 10.5가 들어가있다.
고로 위 방식대로 업데이트 해버리면 tax: 20.2 값이 10.5로 바뀌어버린다.
이 문제를 해결하는 방법은 이전에 배웠다.
Pydantic's model의 dict()함수에서 exclude_unset을 이용하면 된다.
dict자료형을 만들어 주면서 unset된 데이터들을 제외해준다.
from typing import List, Optional
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
price: Optional[float] = None
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
return items[item_id]
@app.patch("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
stored_item_data = items[item_id]
stored_item_model = Item(**stored_item_data)
update_data = item.dict(exclude_unset=True)
updated_item = stored_item_model.copy(update=update_data)
items[item_id] = jsonable_encoder(updated_item)
return updated_item
stored_item_data = items[item_id]
stored_item_model = Item(**stored_item_data)
update_data = item.dict(exclude_unset=True)
updated_item = stored_item_model.copy(update=update_data)
items[item_id] = jsonable_encoder(updated_item)
위 코드에서 데이터를 업데이트 해줄 때 copy() 함수에서 update 파라미터를 이용한것을 주목하자.
즉 정리하자면 데이터 업데이트는 다음과 같이 이루어진다.
- PATCH나 PUT operation을 이용한다
- 저장된 데이터를 가져온다
- 저장된 데이터를 Pydantic Model로 바꾸어준다
- request data를 dict()로 바꾼다. 바꿀때 exclude_unset을 해줌을 기억하자
- 저장된 데이터에서 copy() 메소드를 이용하여 업데이트된 아이템을 얻는다
- 업데이트된 아이템을 jsonable_encoder를 이용하여 json compatiable 데이터로 변환한다
- db에 변환된 아이템을 저장한다.
- db를 업데이트한다
반응형
'Fast API > fastapi배우기' 카테고리의 다른 글
Fast API 배우기 20부 - Security, authentication 인증 시스템 (2) | 2021.11.04 |
---|---|
Fast API 배우기 19부 - Dependency Injection (4) | 2021.11.03 |
Fast API 배우기 17부 - Path Operation Configuration (0) | 2021.11.03 |
Fast API 배우기 16부 - Handling Errors (1) | 2021.11.02 |
Fast API 배우기 15부 - Request Files (1) | 2021.11.02 |
댓글