Thursday, September 15, 2011

Django ORM DB Transactions to Speed Up Bulk Insert

Using Django means you are bounded to Django ORM. Of course one can use other DB ORM, but then loose many neat features in django, such as admin interface and model forms. Lots of tinkering around required when not using Django ORM.
I had a problem when inserting many data using Django ORM. The performance was unacceptably slow. Just to insert 30 data requires more than 10 seconds. How about inserting 50, 100 or more. That is because each time I called save method in the model, Django ORM will execute and commit it immediately, and resulted in performance issue.
Luckily there is a a way to speed up large number of data insert. Django provides a way to manage database transaction, and the way to use it is pretty simple. What we need is TransactionMiddleware. Autocommit is used by default by the transaction manager. In order to speed things up, we need to change it to commit only on succes, simply by using commit_on_succes decorator for the related view.

Now, you need to have TransactionMiddleware registered in settings.py, so it will look like the following:

MIDDLEWARE_CLASSES = (
...
    'django.middleware.transaction.TransactionMiddleware',
...
)


After that, you can use it in your views.py like the following:

from django.db import transaction

@transaction.commit_on_success
def viewfunc(request):
    # ...
    # this code executes inside a transaction
    # ...


By doing that, if the function returns successfully, then Django will commit all work done within the function at that point. If the function raises an exception, though, Django will roll back the transaction. All of those means faster performance.

Please refer to here for more details about django transaction management.

No comments:

Post a Comment