Going beyond Django ORM limitations with Postgres

80
G!"#$ b%&!#’ ()% D*+#$! ORM ,"-"(+("!#. w"() P/($r%. @0r+"$1%r.("%#.

Transcript of Going beyond Django ORM limitations with Postgres

Page 1: Going beyond Django ORM limitations with Postgres

G!"#$ b%&!#' ()% D*+#$! ORM

,"-"(+("!#. w"() P/($r%.

@0r+"$1%r.("%#.

Page 2: Going beyond Django ORM limitations with Postgres

Postgres.app

PSA: Macs

Page 3: Going beyond Django ORM limitations with Postgres

Why Postgres

http://www.craigkerstiens.com/2012/04/30/why-postgres/https://speakerdeck.com/craigkerstiens/postgres-demystified

“Its the emacs of databases”

Page 4: Going beyond Django ORM limitations with Postgres

DatatypesConditional IndexesTransactional DDL

Foreign Data WrappersConcurrent Index Creation

ExtensionsCommon Table Expressions

Fast Column AdditionListen/Notify

Table InheritancePer Transaction sync replication

Window functionsNoSQL inside SQL

Momentum

TLDR

Page 5: Going beyond Django ORM limitations with Postgres

Limitations?Django attempts to support as many features as possible on all database backends. However, not all database backends are alike, and we’ve had to make design decisions on which features to support and which assumptions we can make safely.

Page 6: Going beyond Django ORM limitations with Postgres

D+(+(2%.

Page 7: Going beyond Django ORM limitations with Postgres

__________ < Postgres > ---------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||

Page 8: Going beyond Django ORM limitations with Postgres

Datatypes

smallint bigint integer

numeric floatserial money char

varchartext

bytea

timestamp

timestamptz date

timetimetz

interval boolean

enum

pointline

polygon

box

circle

path

inetcidr

macaddr tsvector

tsquery

arrayXML

UUID

Page 9: Going beyond Django ORM limitations with Postgres

Datatypes

smallint bigint integer

numeric floatserial money char

varchartext

bytea

timestamp

timestamptz date

timetimetz

interval boolean

enum

pointline

polygon

box

circle

pathcidr

macaddr tsvector

tsquery

arrayXML

UUID

inet

Page 10: Going beyond Django ORM limitations with Postgres

Datatypes

smallint bigint integer

numeric floatserial money char

varchartext

bytea

timestamp

timestamptz date

timetimetz

interval boolean

enum

pointline

polygon

box

circle

pathcidr

macaddr tsvector

tsquery

arrayXML

UUID

inet

Page 11: Going beyond Django ORM limitations with Postgres

Datatypes

smallint bigint integer

numeric floatserial money char

varchartext

bytea

timestamp

timestamptz date

timetimetz

interval boolean

enum

pointline

polygon

box

circle

pathcidr

macaddr tsvector

tsquery

arrayXML

UUID

inet

Page 12: Going beyond Django ORM limitations with Postgres

_______ < SQLite > --------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||

Page 13: Going beyond Django ORM limitations with Postgres

Datatypesnull

realtext

blob

integer

Page 14: Going beyond Django ORM limitations with Postgres

Datatypes

smallint bigint integer

numeric floatserial money char

varchartext

bytea

timestamp

timestamptz date

timetimetz

interval boolean

enum

pointline

polygon

box

circle

path

inetcidr

macaddr tsvector

tsquery

arrayXML

UUID

Page 15: Going beyond Django ORM limitations with Postgres

I#'3%.

Page 16: Going beyond Django ORM limitations with Postgres

________ < Postgres > ---------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||

Page 17: Going beyond Django ORM limitations with Postgres

IndexesMultiple Types

B-Tree, Gin, Gist, KNN, SP-Gist

CREATE INDEX CONCURRENTLY

Page 18: Going beyond Django ORM limitations with Postgres

_____ < MySQL > ------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||

Page 19: Going beyond Django ORM limitations with Postgres

IndexesThey exist

Page 20: Going beyond Django ORM limitations with Postgres

Digging In

Page 21: Going beyond Django ORM limitations with Postgres

ArraysCREATE TABLE item ( id serial NOT NULL, name varchar (255), tags varchar(255) [], created_at timestamp);

Page 22: Going beyond Django ORM limitations with Postgres

ArraysCREATE TABLE item ( id serial NOT NULL, name varchar (255), tags varchar(255) [], created_at timestamp);

Page 23: Going beyond Django ORM limitations with Postgres

ArraysINSERT INTO itemVALUES (1, 'Django Pony', '{“Programming”,”Animal”}', now());

INSERT INTO item VALUES (2, 'Ruby Gem', '{“Programming”,”Jewelry”}', now());

Page 24: Going beyond Django ORM limitations with Postgres

ArraysINSERT INTO itemVALUES (1, 'Django Pony', '{“Programming”,”Animal”}', now());

INSERT INTO item VALUES (2, 'Ruby Gem', '{“Programming”,”Jewelry”}', now());

Page 25: Going beyond Django ORM limitations with Postgres

Djangopip install djorm-ext-pgarraypip install djorm-ext-expressions

models.py:

from djorm_pgarray.fields import ArrayFieldfrom djorm_expressions.models import ExpressionManager

class Item(models.Model): name = models.CharField(max_length=255) tags = ArrayField(dbtype="varchar(255)") created_at = models.DateTimeField(auto_now=True)

Page 26: Going beyond Django ORM limitations with Postgres

Djangopip install djorm-ext-pgarraypip install djorm-ext-expressions

models.py:

from djorm_pgarray.fields import ArrayFieldfrom djorm_expressions.models import ExpressionManager

class Item(models.Model): name = models.CharField(max_length=255) tags = ArrayField(dbtype="varchar(255)") created_at = models.DateTimeField(auto_now=True)

Page 27: Going beyond Django ORM limitations with Postgres

Djangoi = Item( name='Django Pony', tags=['Programming','Animal'])i.save()

qs = Item.objects.where( SqlExpression("tags", "@>", ['programming']))

Page 28: Going beyond Django ORM limitations with Postgres

Djangoi = Item( name='Django Pony', tags=['Programming','Animal'])i.save()

qs = Item.objects.where( SqlExpression("tags", "@>", ['programming']))

Page 29: Going beyond Django ORM limitations with Postgres

dblink hstore

citext

ltreeisncube

pgcrypto

tablefunc

uuid-ossp

earthdistance

trigram

fuzzystrmatch

pgrowlocks

pgstattuple

btree_gist

dict_intdict_xsynunaccent

Extensions

Page 30: Going beyond Django ORM limitations with Postgres

NoSQL in your SQL

Page 31: Going beyond Django ORM limitations with Postgres

NoSQL in your SQLCREATE EXTENSION hstore;CREATE TABLE item ( id integer NOT NULL, name varchar(255), data hstore,);

Page 32: Going beyond Django ORM limitations with Postgres

NoSQL in your SQLCREATE EXTENSION hstore;CREATE TABLE item ( id integer NOT NULL, name varchar(255), data hstore,);

Page 33: Going beyond Django ORM limitations with Postgres

NoSQL in your SQLINSERT INTO items VALUES (1, 'Pony', 'rating => "4.0", color => “Pink”', );

Page 34: Going beyond Django ORM limitations with Postgres

NoSQL in your SQLINSERT INTO items VALUES (1, 'Pony', 'rating => "4.0", color => “Pink”', );

Page 35: Going beyond Django ORM limitations with Postgres

Djangopip install django-hstore

from django.db import modelsfrom django_hstore import hstore

class Item(models.Model): name = models.CharField(max_length=250) data = hstore.DictionaryField(db_index=True) objects = hstore.Manager()

def __unicode__(self): return self.name

Page 36: Going beyond Django ORM limitations with Postgres

Djangopip install django-hstore

from django.db import modelsfrom django_hstore import hstore

class Item(models.Model): name = models.CharField(max_length=250) data = hstore.DictionaryField(db_index=True) objects = hstore.Manager()

def __unicode__(self): return self.name

Page 37: Going beyond Django ORM limitations with Postgres

DjangoItem.objects.create( name='Django Pony', data={'rating': '5'})

Item.objects.create( name='Pony', data={'color': 'pink', 'rating': '4'})

Page 38: Going beyond Django ORM limitations with Postgres

DjangoItem.objects.create( name='Django Pony', data={'rating': '5'})

Item.objects.create( name='Pony', data={'color': 'pink', 'rating': '4'})

Page 39: Going beyond Django ORM limitations with Postgres

Djangocolored_ponies = Product.objects.filter(data__contains='color')print colored_ponies[0].data['color']

favorite_ponies = Product.objects.filter(data__contains={'rating': '5'})print colored_ponies[0]

Page 40: Going beyond Django ORM limitations with Postgres

Djangocolored_ponies = Product.objects.filter(data__contains='color')print colored_ponies[0].data['color']

favorite_ponies = Product.objects.filter(data__contains={'rating': '5'})print colored_ponies[0]

Page 41: Going beyond Django ORM limitations with Postgres
Page 42: Going beyond Django ORM limitations with Postgres

JSON

Page 43: Going beyond Django ORM limitations with Postgres

JSON

w/ PLV8

Page 44: Going beyond Django ORM limitations with Postgres

Q4%4%"#$

Page 45: Going beyond Django ORM limitations with Postgres
Page 46: Going beyond Django ORM limitations with Postgres

Pub/Sub?

Page 47: Going beyond Django ORM limitations with Postgres

Postgres a great Queue

Page 48: Going beyond Django ORM limitations with Postgres

Postgres a great Queue

Not With Polling

Page 49: Going beyond Django ORM limitations with Postgres

Trunkpip install celery trunk

psql < sql/*.sqlcelery worker -A tasks --loglevel=info

ipython -i tasks.py>>> add.delay(2, 2)

Page 50: Going beyond Django ORM limitations with Postgres

Trunkpip install celery trunk

psql < sql/*.sqlcelery worker -A tasks --loglevel=info

ipython -i tasks.py>>> add.delay(2, 2)

Page 51: Going beyond Django ORM limitations with Postgres

Trunkfrom celery import Celery

celery = Celery('tasks')celery.config_from_object({ 'BROKER_URL': 'trunk.transport.Transport://localhost/trunk',})

@celery.taskdef add(x, y): return x + y

Page 52: Going beyond Django ORM limitations with Postgres

Trunkfrom celery import Celery

celery = Celery('tasks')celery.config_from_object({ 'BROKER_URL': 'trunk.transport.Transport://localhost/trunk',})

@celery.taskdef add(x, y): return x + y

Page 53: Going beyond Django ORM limitations with Postgres

T3( S%+r0)

Page 54: Going beyond Django ORM limitations with Postgres

Searching Text

Page 55: Going beyond Django ORM limitations with Postgres

Searching Text

Lucene

Sphinx

Elastic Search

Solr

Page 56: Going beyond Django ORM limitations with Postgres

Searching Text

Lucene

Sphinx

Elastic Search

SolrPostgres

Page 57: Going beyond Django ORM limitations with Postgres

Full Text SearchCREATE TABLE posts ( id serial, title varchar(255), content text, tags varchar(255)[], post_text tsvector);

CREATE INDEX posttext_gin ON posts USING GIN(post_text);

CREATE TRIGGER update_posttext BEFORE INSERT OR UPDATE ON postsFOR EACH ROW EXECUTE PROCEDUREtsvector_update_trigger( ‘PostText’,‘english’,title, content, tags);

Page 58: Going beyond Django ORM limitations with Postgres

Full Text SearchCREATE TABLE posts ( id serial, title varchar(255), content text, tags varchar(255)[], post_text tsvector);

CREATE INDEX posttext_gin ON posts USING GIN(post_text);

CREATE TRIGGER update_posttext BEFORE INSERT OR UPDATE ON postsFOR EACH ROW EXECUTE PROCEDUREtsvector_update_trigger( ‘PostText’,‘english’,title, content, tags);

Page 59: Going beyond Django ORM limitations with Postgres

Djangofrom djorm_pgfulltext.models import SearchManagerfrom djorm_pgfulltext.fields import VectorFieldfrom django.db import models

class Posts(models.Model): title = models.CharField(max_length=200) content = models.TextField()

search_index = VectorField()

objects = SearchManager( fields = ('title', 'content'), config = 'pg_catalog.english', search_field = 'search_index', auto_update_search_field = True )

Page 60: Going beyond Django ORM limitations with Postgres

Djangofrom djorm_pgfulltext.models import SearchManagerfrom djorm_pgfulltext.fields import VectorFieldfrom django.db import models

class Posts(models.Model): title = models.CharField(max_length=200) content = models.TextField()

search_index = VectorField()

objects = SearchManager( fields = ('title', 'content'), config = 'pg_catalog.english', search_field = 'search_index', auto_update_search_field = True )

Page 61: Going beyond Django ORM limitations with Postgres

Django

Post.objects.search("documentation & about")

Post.objects.search("about | documentation")

Page 62: Going beyond Django ORM limitations with Postgres

Django

Post.objects.search("documentation & about")

Post.objects.search("about | documentation")

Page 63: Going beyond Django ORM limitations with Postgres

I#'3%.

Page 64: Going beyond Django ORM limitations with Postgres

IndexesB-TreeGeneralized Inverted Index (GIN)Generalized Search Tree (GIST)K Nearest Neighbors (KNN)Space Partitioned GIST (SP-GIST)

Page 65: Going beyond Django ORM limitations with Postgres

Indexes

Which do I use?

Page 66: Going beyond Django ORM limitations with Postgres

IndexesB-TreeGeneralized Inverted Index (GIN)Generalized Search Tree (GIST)K Nearest Neighbors (KNN)Space Partitioned GIST (SP-GIST)

Page 67: Going beyond Django ORM limitations with Postgres

Generalized Inverted Index (GIN)

Use with multiple values in 1 columnArray/hStore

Page 68: Going beyond Django ORM limitations with Postgres

Generalized Search Tree (GIST)Full text searchShapesPostGIS

Page 69: Going beyond Django ORM limitations with Postgres

IndexesB-TreeGeneralized Inverted Index (GIN)Generalized Search Tree (GIST)K Nearest Neighbors (KNN)Space Partitioned GIST (SP-GIST)

Page 70: Going beyond Django ORM limitations with Postgres

G%!Sp+("+,

Page 72: Going beyond Django ORM limitations with Postgres

O#% M!r%

Page 73: Going beyond Django ORM limitations with Postgres

Connections

Page 74: Going beyond Django ORM limitations with Postgres

Connections

django-postgrespooldjorm-ext-pooldjango-db-pool

Page 75: Going beyond Django ORM limitations with Postgres

django-postgrespoolimport dj_database_urlimport django_postgrespool

DATABASE = { 'default': dj_database_url.config() }DATABASES['default']['ENGINE'] = 'django_postgrespool'

SOUTH_DATABASE_ADAPTERS = { 'default': 'south.db.postgresql_psycopg2'}

Page 76: Going beyond Django ORM limitations with Postgres

django-postgrespoolimport dj_database_urlimport django_postgrespool

DATABASE = { 'default': dj_database_url.config() }DATABASES['default']['ENGINE'] = 'django_postgrespool'

SOUTH_DATABASE_ADAPTERS = { 'default': 'south.db.postgresql_psycopg2'}

Page 77: Going beyond Django ORM limitations with Postgres

Limitations?Django attempts to support as many features as possible on all database backends. However, not all database backends are alike, and we’ve had to make design decisions on which features to support and which assumptions we can make safely.

Page 78: Going beyond Django ORM limitations with Postgres

P/($r%.

Its great

Page 79: Going beyond Django ORM limitations with Postgres

D*+#$! ORM

Its not so bad

Page 80: Going beyond Django ORM limitations with Postgres

5+#1.!