Code Defensively to Avoid KeyErrors and Other Bugs

One of the tradeoffs of a document-oriented database versus a relational database is that the database does not enforce schema for you. For this reason, when working with MongoDB you must be vigilant in your handling of database results. Do not blindly assume that results will always have the properties you expect.

Check for their presence before accessing them. Although Python will generally raise a KeyError and stop execution, depending on your application this still may result in loss of data integrity. Consider the case of updating every document in a collection one-by-one—a single unforeseen KeyError could leave the database in an inconsistent state, with some documents having been updated and others not.

For example,

all_user_emails = []
for username in ("jill", "sam", "cathy"):
    user_doc = dbh.users.find_one({"username":username})
    # KeyError will be raised if any of these does not exist
    dbh.emails.insert({"email":user_doc["email"]})

Sometimes you will want to have a default fallback to avoid KeyErrors should a document be returned which is missing a property required by your program. The Python dict class’ get method easily lets you specify a default value for a property should it be missing.

Often it makes sense to use this defensively. For example, imagine we have a collection of user documents. Some users have a “score” property set to a number, while others do not. It would be safe to have a default fallback of zero (0) in ...

Get MongoDB and Python now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.