Obtaining the document causing DuplicateKeyError exception to be thrown

82 views
Skip to first unread message

K E

unread,
Mar 24, 2015, 7:54:08 PM3/24/15
to mongod...@googlegroups.com
I'm using PyMongo 2.8 in my application, and I'm trying to get the document existing in the database that caused the DuplicateKeyError

When I add a document to the database and there is a conflict, then a DuplicateKeyError exception is thrown. Under what circumstances is details on the exception not None?
It seemed like I should be able to do something along these lines:

    except DuplicateKeyError as e:
        doc = e.details
        # Handle exception

Bernie Hackett

unread,
Mar 24, 2015, 9:10:08 PM3/24/15
to mongod...@googlegroups.com
e.details includes the error document returned by the server:

>>> c.test.test.insert({'_id': 1})
1
>>> from pymongo.errors import DuplicateKeyError
>>> try:
...     c.test.test.insert({'_id': 1})
... except DuplicateKeyError as exc:
...     print exc.details
... 
{u'index': 0, u'code': 11000, u'errmsg': u'E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }'}

Unfortunately you would have to parse the value of the "errmsg" field to find the field and value that caused the error. If you are getting this when calling Collection.insert, you already now the values of all the keys (insert() modifies the document you passed in to add _id if the document doesn't already include it). If you're getting DuplicateKeyError from update() you will have to parse the error document to find this information.

K E

unread,
Mar 25, 2015, 3:14:47 PM3/25/15
to mongod...@googlegroups.com
I'm not getting anything from details. I'm getting None.

Using Ming and PyMongo:

        try:
            model = Model(**data)
            model.__class__.__mongometa__.session.flush(model)
        except DuplicateKeyError as e:
            import pdb; pdb.set_trace()

(pdb) p e.details
None

-----------------------------

Since I'm using Ming though, I was able to use __mongometa__ to work around it, but it seems overly complicated.


            if hasattr(metadata, 'custom_indexes') and metadata.custom_indexes:
                indexes = metadata.custom_indexes
                expressions = []
                for index in indexes:
                    if index.get('unique', False):
                        fields = index['fields']
                        query = {}
                        for field in fields:
                            query[field] = data.get(field, None)
                        expressions.append(query)

            if hasattr(metadata, 'unique_indexes') and metadata.unique_indexes:
                indexes = metadata.unique_indexes
                expressions = []
                for index in indexes:
                    query = {}
                    for field in index:
                        query[field] = data.get(field, None)
                    expressions.append(query)

            model = Model.query.find({'$or': expressions}).first()

K E

unread,
Mar 25, 2015, 3:18:04 PM3/25/15
to mongod...@googlegroups.com
I forgot to include in my work around that metadata = Model.__mongometa__

Bernie Hackett

unread,
Mar 25, 2015, 6:45:16 PM3/25/15
to mongod...@googlegroups.com
Are you using mim? It seems to raise DuplicateKeyError itself, not added any details about what happened:

K E

unread,
Mar 26, 2015, 1:24:26 PM3/26/15
to mongod...@googlegroups.com
I was using MIM. I was using MIM with a test case to ensure the functionality would work before deciding if I would want to use it on a live site.

K E

unread,
Mar 26, 2015, 1:28:56 PM3/26/15
to mongod...@googlegroups.com
Posted prematurely. I'll try modifying that line in Ming. Thanks for your help.
Reply all
Reply to author
Forward
0 new messages