好吧,如果我说得不太明白,请原谅。每当我运行collections.find()
函数时,我都会遇到这个'ObjectId' object is not iterable
。在浏览这里的答案时,我不确定从哪里开始。我是编程新手,请耐心听我说。
每次我访问从Mongodb获取数据的路线时,我都会得到ValueError: [TypeError("'ObjectId' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
。
帮助
发布于 2021-11-05 18:32:13
首先,如果我们有一些你的代码的例子,这将会容易得多。我只能假设您没有正确地将MongoDb集合数据映射到Pydantic BaseModel。
读取this:MongoDB将数据存储为BSON。FastAPI将数据编码和解码为JSON字符串。BSON支持其他非JSON原生数据类型,包括不能直接编码为JSON的ObjectId。因此,在将ObjectIds存储为_id之前,我们将其转换为字符串。我想让大家注意这个模型上的id字段。MongoDB使用_id,但在Python中,属性开头的下划线具有特殊含义。如果你的模型上有一个以下划线开头的属性,pydantic-FastAPI使用的数据验证框架-将假定它是一个私有变量,这意味着你不能给它赋值!为了解决这个问题,我们将字段命名为id,但给它一个别名_id。您还需要在模型的Config类中将allow_population_by_field_name设置为True。
下面是一个有效的示例:
首先创建BaseModel:
class PyObjectId(ObjectId):
""" Custom Type for reading MongoDB IDs """
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
if not ObjectId.is_valid(v):
raise ValueError("Invalid object_id")
return ObjectId(v)
@classmethod
def __modify_schema__(cls, field_schema):
field_schema.update(type="string")
class Student(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
first_name: str
last_name: str
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True
json_encoders = {ObjectId: str}
现在只需解开所有内容:
async def get_student(student_id) -> Student:
data = await collection.find_one({'_id': student_id})
if data is None:
raise HTTPException(status_code=404, detail='Student not found.')
student: Student = Student(**data)
return student
https://stackoverflow.com/questions/63881516
复制相似问题