[Answer]-Django + MySQL IntegrityError on save()

1👍

The save method is subject to a race condition regarding the primary key. It first determines if a record with that primary key exists, and if it does an update statement is executed, otherwise an insert statement is executed. If a concurrent requests inserts a new record between these two queries, there will be an integrity error.

The following will handle a race condition (unless records are deleted in between queries):

import sys
from django.utils import six

try:
    obj.save()
except IntegrityError:
    # The save might have been subject to a race condition. 
    # If it is, a record with this object's pk exists, so try to update it. 
    exc_info = sys.exc_info()
    try:
        obj.save(force_update=True)
    except:
        six.reraise(*exc_info)

If something else is wrong, this will raise the first, initial exception, so there are no hidden IntegrityErrors besides the one that are caused by this race condition. I know it’s a little verbose for a simple save, but you can always override the save method on your model to do this for you.

Leave a comment