Django 1.9's Improvements for Postgres

A big update to the beloved Python web framework known as Django was released recently: Django 1.9. This release contains a long list of improvements for everything from the graphical styling of the admin to the ability to run your test suite in parallel.

Our favorite improvements to the framework were, of course, all about our favorite database: Postgres. Here are some of the highlights from the official release notes (highly recommended reading).

Renamed PostgreSQL Back-end

Django's fantastic built-in Postgres database back-end received a nice name change. Previously known as django.db.backends.postgresql_psycopg2, the back-end will now be officially available as the much easier to remember django.db.backends.postgresql.

There is now no question that psycopg2 is the database driver to use when interacting with Postgres from Python. However, the old name will continue to work, for backwards compatibility.

JSONField

The release of Django 1.8 brought us built-in support for Postgres' useful HSTORE data type, via HStoreField, but the release of Django 1.9 has us even more excited. Django now ships with full support for Postgres' indexable JSONB datatype, as JSONField.

Here's an example of what JSONField allows us to easily do within Django models:

Profile.objects.create(
    name='Arthur Dent',
    info={
         'residences': [
             {'name': 'Earth', 'type': 'planet', 'status': 'destroyed'},
             {'name': 'Heart of Gold', 'type': 'ship'}
         ]
    }
)

Before, without JSONField, this simple metadata would require a dedicated residences table, with a status column that would rarely be utilized. With JSONB, you have total flexibility of the shape of your data, without over-burdening your database schema.

You can query the data, which can be fully indexed by Postgres, just as easily:

>>> Profile.objects.filter(info__residences__contains={'name': 'Earth'})
[<Profile: Arthur Dent>]

JSONB is available on Postgres versions 9.4 and above, on all Heroku Postgres plans.

Database Transaction Commit Hooks

Django's database innards have a new hook available for executing a callable after a database transaction has been committed successfully: on_commit(). The code originates from the django-transaction-hooks project, which has been fully integrated into Django proper.

Here's an example of using on_commit() with WebHooks:

from datetime import datetime

import requests
from django.db import connection

def alert_webservice():
    """Alerts webservice of database transaction events."""

    # Prepare WebHook payload.
    time = datetime.utcnow().isoformat()
    data = {'event': {'type': 'transaction', 'time': time}}

    # Sent the payload to the webservice.
    r = requests.post('https://httpbin.org/post', data=data)
       
    # Ensure that request was successful.
    assert r.ok
       
# Register alert_webservice transaction hook.
connection.on_commit(alert_webservice)

Deploy Django 1.9 on Heroku Today

As always, Django 1.9 is fully supported by Heroku Python. Click the deploy button below to instantly deploy a free instance of a Django 1.9 application to your Heroku account, ready for hacking.

Deploy

Browse the blog archives, subscribe to the full-text feed, or visit the engineering blog.