Alex Husar
Alex Husar

Reputation: 49

Python mongodb/motor "'ObjectId' object is not iterable" error while trying to find item in collection

I know that there are similar questions, but I've tried everything that was advised and still getting an error. I'm trying to fetch item from mongo collection by id, converting string to an ObjectId, like that:

from bson import ObjectId


async def get_single_template(db, template_id):
    template = await db.templates.find_one({ '_id': ObjectId(template_id) })
    return template

And I'm getting an error:

ValueError: [TypeError("'ObjectId' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]

"template_id" is a valid string, like "601401887ecf2f6153bbaaad". ObjectId created from it - too. It fails only to work inside find_one() method. When I'm using find() with that id it works well. I've tried from bson.objectid import ObjectId too - no difference. I'm using motor library to access mongo. Is there something that I'm missing?

P.S. Links to the corresponding docs:

https://pymongo.readthedocs.io/en/stable/tutorial.html#querying-by-objectid

Though I'm using motor async library, I can't find direct examples in it's docs. Basically, it wraps pymongo. I can only find examples in other's source code.

Upvotes: 1

Views: 4695

Answers (3)

Kashif
Kashif

Reputation: 1454

After long research i find one solution work for me

I try many ways let's discuss with you one of them

DATABASE_URL = mongodb://localhost:portname/yourdbname
client = mongo_client.MongoClient(
  settings.DATABASE_URL#, ServerSelectionTimeoutMS=5000
)
db = client[settings.MONGO_INITDB_DATABASE]
Post = db.post

@router.get('/')
async def posts(user_id: str = Depends(oauth2.require_user)):
list = []
for i in Post.find():
    list.append(i)
print("list", list)
return {'status': 'success', "list":  list}

Everything work on print but when i return the response then show me error that mentioned in post i solve this error by doing this serialize ObjectId with native fastApi methods

at top of my file i just import

from bson.objectid import ObjectId
import pydantic
pydantic.json.ENCODERS_BY_TYPE[ObjectId]=str

Note: I am not expert of fastapi with MongoDB i just start learning last 5 days ago about fastapi and start learning mongoDb last 2 days ago. if you have any better practice then let me know i also trying to serialize data but on that case also not work so try this way thank you

this comment help me from github

https://github.com/tiangolo/fastapi/issues/1515#issuecomment-782838556

Upvotes: 0

Swarnabha Das
Swarnabha Das

Reputation: 37

I encountered this problem as well while using Python motor for Mongodb. In your app.collection.find_one(...), add {'_id': 0} along with the dictionary which has the value you want to search for.

So it should be like this:

await app.collection.find_one({"value": val},{'_id': 0})

Upvotes: 2

Alex Husar
Alex Husar

Reputation: 49

Well, I've found out what caused that issue. The problem was not in the way I've tried to query data, but in the way I've tried to return it. I've forgotten to convert ObjectId to string in the entity that I've retrieved from database and tried to return it 'as is'. My bad.

Upvotes: 3

Related Questions