24. Body - Updates
1. Body - Updates
- 이미 저장된 body를 업데이트할 수 있는 몇 가지 방법이 있다.
2. Update replacing with PUT
- 항목을 업데이트하기 위해 HTTP
PUT
operation을 사용할 수 있다.
- 다음의 예제는
jsonable_encoder
를 사용하여 입력 데이터를 JSON으로 저장할 수 있는 데이터로 변환하는 예제이다.
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
PUT
operation은 기존 데이터를 대체해야 하는 상황에서 사용된다.
1) Warning about replacing
- 다음과 같이
PUT
operation을 사용하여bar
항목을 업데이트한다고 가정해 보자.
- 위와 같이 업데이트하는 경우, 이미 저장된 속성
"tax": 20.2
를 더 이상 포함하지 않기 때문에 입력 모델은 기본값인"tax": 10.5
를 사용하게 된다. - 그러므로 업데이트된 새로운 데이터는
"tax": 10.5
로 저장된다.
3. Partial updates with PATCH
- 항목의 일부분만 업데이트하기 위해 HTTP
PATCH
operation을 사용할 수 있다. - 즉, 항목의 나머지는 그대로 두고 업데이트하려는 데이터만 보낼 수 있다.
Note
- 하지만 일반적으로
PATCH
보다PUT
을 더 많이 사용한다.
1) Using Pydantic's exclude_unset
parameter
- 부분적으로 업데이트를 하고 싶다면
item.dict(exclude_unset=True)
와 같이 Pydantic 모델의.dict()
에서exclude_unset
매개변수를 사용하는 것이 유용하다. - 이렇게 하면, 기본값을 제외하고 항목 모델을 생성할 때 새로 설정한 데이터만 포함하는
dict
가 생성된다.
- 다음의 예제는 기본값을 생략하고 새로 설정된 데이터만 포함하는
dict
를 생성하는 예제이다.
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
2) Using Pydantic's update
parameter
stored_item_model.copy(update=update_data)
와 같이.copy()
를 사용하여 기존 모델의 복사본을 만들고 업데이트할 데이터가 포함된dict
와 함께update
매개변수를 전달할 수 있다.
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