First-class Postgres feature support for the Django ORM.
Python Shell
Switch branches/tags
Nothing to show
Pull request Compare This branch is 5 commits ahead of zacharyvoase:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
django_postgres
doc
tests
.gitignore
MANIFEST.in
README.md
UNLICENSE
setup.py

README.md

django-postgres

Adds first-class support for PostgreSQL features to the Django ORM.

Planned features include:

Obviously this is quite a large project, but I think it would provide a huge amount of value to Django developers.

Why?

PostgreSQL is an excellent data store, with a host of useful and efficiently-implemented features. Unfortunately these features are not exposed through Django's ORM, primarily because the framework has to support several SQL backends and so can only provide a set of features common to all of them.

The features made available here replace some of the following practices:

  • Manual denormalization on save() (such that model saves may result in three or more separate queries).
  • Sequences represented by a one-to-many, with an order integer field.
  • Complex types represented by JSON in a text field.

Example

The following represents a whirlwind tour of potential features of the project:

from django.db import models
import django_postgres as pg


USStates = pg.Enum('states_of_the_usa', ['AL', ..., 'WY'])


class Address(pg.CompositeType):
    line1 = models.CharField(max_length=100)
    line2 = models.CharField(max_length=100, blank=True)
    city = models.CharField(max_length=100)
    zip_code = models.CharField(max_length=10)
    state = USStates()
    country = models.CharField(max_length=100)


class USPhoneNumber(pg.Domain):
    data_type = models.CharField(max_length=10)
    constraints = [
      r"VALUE ~ '^\d{3}-?\d{3}-?\d{4}$'"
    ]


class Customer(models.Model):
    name = models.CharField(max_length=100)
    shipping_address = Address()
    telephone_numbers = pg.Array(USPhoneNumber())
    is_preferred = models.BooleanField(default=False)


class PreferredCustomer(pg.View):
    projection = ['myapp.Customer.*']
    sql = """SELECT * FROM myapp_customer WHERE is_preferred = TRUE;"""

The SQL produced by this might look like:

CREATE TYPE states_of_the_usa AS ENUM ('AL', ..., 'WY');

CREATE TYPE myapp_address AS (
    line1 varchar(100),
    line2 varchar(100),
    city varchar(100),
    zip_code varchar(10),
    state states_of_the_usa,
    country varchar(100)
);

CREATE DOMAIN myapp_usphonenumber AS varchar(10)
    CHECK(VALUE ~ '^\d{3}-?\d{3}-?\d{4}$');

CREATE TABLE myapp_customer (
    id SERIAL PRIMARY KEY,
    shipping_address myapp_address,
    telephone_numbers myapp_usphonenumber[]
);

CREATE VIEW myapp_preferredcustomer AS
SELECT * FROM myapp_customer WHERE is_preferred = TRUE;

To create all your views, run python manage.py sync_pgviews