简体   繁体   English

"ObjectId' object is not iterable" 错误,同时从 MongoDB Atlas 中获取数据

[英]"ObjectId' object is not iterable" error, while fetching data from MongoDB Atlas

Okay, so pardon me if I don't make much sense.好吧,如果我没有多大意义,请原谅我。 I face this 'ObjectId' object is not iterable whenever I run the collections.find() functions.每当我运行collections.find()函数时,我都会遇到这个'ObjectId' object is not iterable Going through the answers here, I'm not sure where to start.通过这里的答案,我不知道从哪里开始。 I'm new to programming, please bear with me.我是编程新手,请耐心等待。

Every time I hit the route which is supposed to fetch me data from Mongodb, I get ValueError: [TypeError("'ObjectId' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')] .每次我点击应该从 Mongodb 获取数据的路线时,我都会收到ValueError: [TypeError("'ObjectId' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]

Help帮助

I was having a similar problem to this myself.我自己也有类似的问题。 Not having seen your code I am guessing the traceback similarly traces the error to FastAPI/Starlette not being able to process the "_id" field - what you will therefore need to do is change the "_id" field in the results from an ObjectId to a string type and rename the field to "id" (without the underscore) on return to avoid incurring issues with Pydantic.没有看到你的代码我猜回溯类似地将错误追溯到 FastAPI/Starlette 无法处理“_id”字段 - 因此你需要做的是将结果中的“_id”字段从ObjectId更改为字符串类型,并在返回时将字段重命名为“id”(不带下划线)以避免与 Pydantic 发生问题。

从输出中排除“_id”。

result = collection.find_one({'OpportunityID': oppid}, {'_id': 0})

First of all, if we had some examples of your code, this would be much easier.首先,如果我们有一些您的代码示例,这会容易得多。 I can only assume that you are not mapping your MongoDb collection data to your Pydantic BaseModel correctly.我只能假设您没有将 MongoDb 集合数据正确映射到 Pydantic BaseModel。

Read this : MongoDB stores data as BSON.阅读:MongoDB 数据存储为 BSON。 FastAPI encodes and decodes data as JSON strings. FastAPI 将数据编码和解码为 JSON 字符串。 BSON has support for additional non-JSON-native data types, including ObjectId which can't be directly encoded as JSON. BSON 支持其他非 JSON 原生数据类型,包括不能直接编码为 JSON 的 ObjectId。 Because of this, we convert ObjectIds to strings before storing them as the _id.因此,我们将 ObjectIds 转换为字符串,然后再将它们存储为 _id。 I want to draw attention to the id field on this model.我想提请注意这个模型上的 id 字段。 MongoDB uses _id, but in Python, underscores at the start of attributes have special meaning. MongoDB 使用 _id,但在 Python 中,属性开头的下划线具有特殊含义。 If you have an attribute on your model that starts with an underscore, pydantic—the data validation framework used by FastAPI—will assume that it is a private variable, meaning you will not be able to assign it a value!如果您的模型中有一个以下划线开头的属性,pydantic(FastAPI 使用的数据验证框架)将假定它是一个私有变量,这意味着您将无法为其分配值! To get around this, we name the field id but give it an alias of _id.为了解决这个问题,我们将字段命名为 id,但给它一个别名 _id。 You also need to set allow_population_by_field_name to True in the model's Config class.您还需要在模型的 Config 类中将 allow_population_by_field_name 设置为 True。

Here is a working example:这是一个工作示例:

First create the BaseModel:首先创建 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}

Now just unpack everything:现在只需解压缩所有内容:

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

use db.collection.find(ObjectId:"12348901384918")使用 db.collection.find(ObjectId:"12348901384918")
here db.collection is database name and use double quotes for the string .这里 db.collection 是数据库名称并使用双引号作为字符串。

Use the response model inside app decorator Here is the sample example在 app decorator 中使用响应 model 这是示例

from pydantic import BaseModel
 class Todo(BaseModel):
   title:str
   details:str

main.py主程序

@app.get("/{title}",response_model=Todo)
  async def get_todo(title:str):
  response=await fetch_one_todo(title)
  if not response:
    raise 
         HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail='not found')
  return response

I was trying to iterate through all the documents and what worked for me was this solution https://github.com/tiangolo/fastapi/issues/1515#issuecomment-782835977我试图遍历所有文档,对我有用的是这个解决方案https://github.com/tiangolo/fastapi/issues/1515#issuecomment-782835977

These lines just needed to be added after the child of ObjectID class.这些行只需要在 ObjectID 类的子类之后添加。 An example is given in the following link.以下链接中给出了一个示例。 https://github.com/tiangolo/fastapi/issues/1515#issuecomment-782838556 https://github.com/tiangolo/fastapi/issues/1515#issuecomment-782838556

I had this issue until I upgraded from mongodb version 5.0.9 to version 6.0.0 so mongodb made some changes on their end to handle this if you have the ability to upgrade.在我从 mongodb 版本 5.0.9 升级到版本 6.0.0 之前,我遇到了这个问题,所以 mongodb 如果您有能力升级,则在他们的末端进行了一些更改以处理此问题。 I ran into this issue when creating a test server and when I created a new test server that was 6.0,0.我在创建测试服务器和创建 6.0,0.0 的新测试服务器时遇到了这个问题。 it fixed the error它修复了错误

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python mongodb/motor “'ObjectId' object is not iterable” 尝试在集合中查找项目时出错 - Python mongodb/motor “'ObjectId' object is not iterable” error while trying to find item in collection FastAPI 问题 MongoDB - TypeError: 'ObjectId' object is not iterable - FastAPI issues with MongoDB - TypeError: 'ObjectId' object is not iterable 错误响应:“'NoneType' object 不可迭代”同时从预订中抓取数据 - Error response : "'NoneType' object is not iterable" while scraping the data from booking 使用fastAPI从MongoDb获取数据时出错 - Getting Error while fetching data from MongoDb using fastAPI 从数据库(mysql)获取数据时出错。 n="+".join(n) TypeError: can only join an iterable - getting an error while fetching data from database (mysql). n="+".join(n) TypeError: can only join an iterable TypeError:从HTML解析时,“ Request”对象不是可重复的错误 - TypeError: 'Request' object is not iterable error while Parsing from HTML 从mongodb atlas python读取数据 - reading data from mongodb atlas python 从 Google Colaboratory 连接到 Mongodb Atlas 时出错 - Error connecting to Mongodb Atlas from Google Colaboratory 从容器连接到 Atlas mongoDB 的超时错误 - Timeout error connecting to Atlas mongoDB from a container 从PostgreSQL'builtin_function_or_method'对象获取数据时出错没有属性'execute' - Error while fetching data from PostgreSQL 'builtin_function_or_method' object has no attribute 'execute'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM