MongoDB와 관련된 FastAPI 문제 - TypeError: 'ObjectId' 개체를 인식할 수 없습니다.
FastAPI를 통해 MongoDB에 삽입하는 데 문제가 있습니다.
아래 코드는 예상대로 작동합니다. 변수가 에서 사용되지 않은 방법에 주목하십시오.
는 sklearn ElasticNet 모델입니다.
app = FastAPI()
def response_to_mongo(r: dict):
client = pymongo.MongoClient("mongodb://mongo:27017")
db = client["models"]
model_collection = db["example-model"]
model_collection.insert_one(r)
@app.post("/predict")
async def predict_model(features: List[float]):
prediction = model.predict(
pd.DataFrame(
[features],
columns=model.feature_names_in_,
)
)
response = {"predictions": prediction.tolist()}
response_to_mongo(
{"predictions": prediction.tolist()},
)
return response
그러나 내가 이렇게 쓰고 변수를 전달할 때:
@app.post("/predict")
async def predict_model(features: List[float]):
prediction = model.predict(
pd.DataFrame(
[features],
columns=model.feature_names_in_,
)
)
response = {"predictions": prediction.tolist()}
response_to_mongo(
response,
)
return response
다음과 같은 오류가 표시됩니다.
TypeError: 'ObjectId' object is not iterable
제가 읽은 바로는, 이것은 Fast 간의 BSON/JSON 문제 때문인 것 같습니다.API랑 몽고. 그런데 변수를 사용하지 않는데 첫 번째 경우에는 왜 작동하나요? 이것은 FastAPI의 비동기적 특성 때문입니까?
에 따라:
문서에 아직 키가 없는 경우 특수 키가 삽입되면 자동으로 추가됩니다. 의 값은 컬렉션 전체에서 고유해야 합니다. 의 인스턴스를 반환합니다. "_id"에 대한 자세한 내용은 를 참조하십시오.
따라서 두 번째 경우, 사전을 함수에 전달할 때, Pymongo는 데이터베이스에서 데이터를 검색하는 데 필요한 고유 식별자(즉, )를 사전에 추가합니다. 따라서 엔드포인트에서 응답을 반환할 때, 는 직렬화되지 않습니다(자세히 설명된 바와 같이, 기본적으로 FastAPI는 자동으로 실행됩니다. 를 사용하여 반환 값을 변환한 다음 a)를 반환합니다.
솔루션 1
를 기본적으로 로 변환하여 보여준 방법을 사용하면 엔드포인트 내부에서 평소와 같이 를 반환할 수 있습니다.
# place these at the top of your .py file
import pydantic
from bson import ObjectId
pydantic.json.ENCODERS_BY_TYPE[ObjectId]=str
return response # as usual
솔루션 2
로드된 문자열을 올바른 문자열로 덤프한 다음 및 설명에 따라 로 다시 로드합니다.
from bson import json_util
import json
response = json.loads(json_util.dumps(response))
return response
솔루션 3
설명에 따라 사용자 정의를 정의하여 를 다음으로 변환합니다.
import json
from bson import ObjectId
class JSONEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, ObjectId):
return str(o)
return json.JSONEncoder.default(self, o)
response = JSONEncoder().encode(response)
return response
솔루션 4
항목을 반환하기 전에 사전에서 항목을 제거합니다(에서 키를 제거하는 방법 참조).
response.pop('_id', None)
return response
'개발하자' 카테고리의 다른 글
파이썬의 매트릭스 기본 도움말 (1) | 2023.01.16 |
---|---|
sort values and return list of keys from dict python (0) | 2023.01.15 |
Fast API - 필드 필수, 누락된 값 (0) | 2023.01.14 |
사용자 지정 미들웨어 때문에 Fast API Swager가 렌더링되지 않습니까? (0) | 2023.01.14 |
대화형으로 IPython/Jupyter 노트북 실행 (0) | 2023.01.13 |