I am using PyMongo. Do I have to close a MongoClient after use?

I am using PyMongo, and I have some questions about connection and cursor.

  1. Do I have to close a cursor? I want to know because I really want to do something like this.
 for s in collection.find():
       print(s)
  1. Do I have to close a MongoClient manually? Will it affect the connection polling feature of PyMongo?
from pymongo import MongoClient

url = 'mongodb://localhost:27017'
client = MongoClient(url)               # create MongoClient

db = client['test']                     # client.dbname
collection = db['students']             # db.collname

# QUERY
cursor = collection.find()
for s in cursor:
    print(s)

cursor .close()      # Is this required?
client.close()         # Is this required?
1 Like

https://pymongo.readthedocs.io/en/stable/api/pymongo/mongo_client.html

the document doesn’t say if that is required or not. But generally if a “close” is provided, it’s better to call it when the object is no longer needed. (to save compute resources).

For “client” i suppose it can be kept without closing there until the application terminates (process exits), but for a “cursor” i would suggest to close it when the its use is done.

Thank you for your question.

@Kobe_W is correct, best practice is to call close() when the client is no longer needed or use the client in a with-statement:

with MongoClient(url) as client:
    # use client here

It’s also a good idea to call close() on the cursor too, the best way would be to use a with-statement like this:

with collection.find() as cursor:
    for s in cursor:
        print(s)

When PyMongo’s MongoClient and cursor objects are garbage collected without being closed pymongo will clean up application-side resources automatically (connections, threads, etc…) however some server-side resources could be left open (cursors, sessions). Calling close() explicitly (or using a with-statement) will clean up these server-side resources that would otherwise be left around until they timeout.

I just opened this ticket to improve our documentation around these ideas: https://jira.mongodb.org/browse/PYTHON-3606

4 Likes

So I understand correctly that exhausting the cursor does not close it? I guess failing to close the cursors could cause problems with “too many open files” in the server? It could explain some issues I’m having.

(guess that makes sense since it’s probably possible to call explain etc. after exhaustion)

Exhausting a cursor (ie fully iterating all the results) does close the cursor automatically. Using the cursor in a with-statement is helpful when the cursor is intentionally or accidentally not fully iterated. For example if an exception is raised in the middle of processing the results the cursor with-statement will cleanup the cursor in a more timely manner:

with collection.find() as cursor:
    for s in cursor:
        print(s)
        raise ValueError('oops')
3 Likes

@Shane I too have a similar doubt and didn’t find the conclusion from this discussion… so we should not close client everytime but we should close cursor everytime. Is this the conclusion

Correct, a client should be kept open as long as it is being used and should be closed when the app no longer needs it (or before the application shuts down). This ensures resources like server sessions are cleaned up promptly.

For cursors, this kind of code works:

for doc in collection.find():
    print(doc)

But it is more robust to close the cursor resource explicitly (eg via a with-statement):

with collection.find() as cursor:
    for doc in cursor:
        print(doc)