Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

36
Are you Postgres yet? PyCon Belarus, January 31, 2015 Volodymyr Hotsyk

Transcript of Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Page 1: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Are you Postgres yet?

PyCon Belarus, January 31, 2015 Volodymyr Hotsyk

Page 2: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

About me

• Python developer at GetGoing

• PyCon Ukraine organizer

• github/twitter/gmail: hotsyk

Page 3: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Outline• Why Postgres

• Python + Postgres

• Django support

• Range types

• Array type

• HStore

• JSONType

• Indexes

• Pools/HighLoad

Page 4: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Why Postgres• Window functions

• Flexible Datatypes

• Functions

• Custom Languages

• Extensions

Page 5: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Why Postgres• Foreign Data Wrappers

• Conditional Constraints and Partial Indexes

• Listen/Notify

• Table Inheritance

• Real NoSQL in SQL

Page 6: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Python + Postgres

• Psycopg2

• pg8000

• Python3 + asyncio = aiopg

Page 7: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Django support

• Django ORM designed to work with all supported DBs

• No Postgres specific features

• Third-party apps to add support of specific features

Page 8: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Django support

• kickstarter.com/projects/mjtamlyn/improved-postgresql-support-in-django

Page 9: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

contrib.postgres in 1.8• Specific model fields

• ArrayField

• HStoreField

• Range Fields

• Specific form fields and widgets

• SimpleArrayField

• SplitArrayField

• HStoreField

• Range Fields

• Widgets

• Specific lookups

• Unaccent

• Database migration operations

• CreateExtension

• HStoreExtension

• UnaccentExtension

• Validators

• KeysValidator

• Range validators

Page 10: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Range types• int4range — Range of integer

• int8range — Range of bigint

• numrange — Range of numeric

• tsrange — Range of timestamp without time zone

• tstzrange — Range of timestamp with time zone

• daterange — Range of date

Page 11: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Range types

>CREATE TABLE reservation

(room int, during tsrange);

>INSERT INTO reservation VALUES

(1, '[2015-01-31 14:30, 2015-01-31 15:30)');

Page 12: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Range types + Django

• 1.8: django.contrib.postgres

• 1.7: bitbucket.org/schinckel/django-postgres

Page 13: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Range types + Django

• IntegerRangeField

• BigIntegerRangeField

• FloatRangeField

• DateTimeRangeField

• DateRangeField

Page 14: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Range types>Event.objects.create(name='Meetup', ages=(18, 70))

Query

>Event.objects.filter(ages__contains=NumericRange(20, 35))

>Event.objects.filter(ages__contained_by=NumericRange(0, 55))

>Event.objects.filter(ages__overlap=NumericRange(18, 22))

Page 15: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Range types

Compare

>Event.objects.filter(ages__fully_lt=NumericRange(31, 35))

>Event.objects.filter(ages__adjacent_to=NumericRange(20, 31))

Page 16: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Demo

•github.com/hotsyk/djangopsqltest

Page 17: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Array typeCREATE TABLE tictactoe (squares integer[3][3]);

• Postgres 9.0+

• Django <=1.7: niwibe.github.io/djorm-pgarray

• Django 1.7: bitbucket.org/schinckel/django-postgres/

• Django 1.8: django.contrib.postgres.fields.array

Page 18: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Array typefrom django.db import models

from django.contrib.postgres.fields import ArrayField

class Post(models.Model):

name = models.CharField(max_length=200)

tags = ArrayField(models.CharField(max_length=200), blank=True)

Page 19: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Array type

>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])

>>> Post.objects.create(name='Second post', tags=['thoughts'])

>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])

Page 20: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Array type>>> Post.objects.filter(tags__contains=['django'])

[<Post: First post>, <Post: Third post>]

>>> Post.objects.filter(tags__contains=['django', 'thoughts'])

[<Post: First post>]

Page 21: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Demo

•github.com/hotsyk/djangopsqltest

Page 22: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

HStore

• Key/value store

• Postgres 9.1+

• >create extension hstore;

Page 23: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Django support

• Django <= 1.7: django-hstore

• Django 1.8: contrib.postgres

Page 24: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Demo

•github.com/hotsyk/djangopsqltest/hstore

Page 25: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

JSONType

• Postgres 9.4+

• Document DB in your SQL DB

• Django 1.7: django-jsonfield, django-postgres

• Django 1.9: contrib.postgres

Page 26: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

JSONTypeCREATE TABLE json_test (

id serial primary key,

data jsonb

);

INSERT INTO json_test (data) VALUES

('{}'),

('{"a": 1}'),

('{"a": 2, "b": ["c", "d"]}'),

('{"a": 1, "b": {"c": "d", "e": true}}'),

('{"b": 2}');

Page 27: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

JSONTypeSELECT * FROM json_test;

id | data

----+--------------------------------------

1 | {}

2 | {"a": 1}

3 | {"a": 2, "b": ["c", "d"]}

4 | {"a": 1, "b": {"c": "d", "e": true}}

5 | {"b": 2}

(5 rows)

Page 28: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

JSONTypeSELECT * FROM json_test WHERE data = ‘{"a":1}';

id | data

----+------

1 | {"a": 1}

(1 row)

SELECT * FROM json_test WHERE data @> ‘{"a":1}';

id | data

----+--------------------------------------

2 | {"a": 1}

4 | {"a": 1, "b": {"c": "d", "e": true}}

(2 rows)

Page 29: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

JSONTypeSELECT * FROM json_test WHERE data ?| array['a', 'b'];

id | data

----+--------------------------------------

2 | {"a": 1}

3 | {"a": 2, "b": ["c", "d"]}

4 | {"a": 1, "b": {"c": "d", "e": true}}

5 | {"b": 2}

(4 rows)

Page 30: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

JSONTypeSELECT * FROM json_test WHERE data #> '{b,c}' = '"d"';

Give me objects where element b has a child object that has element c equal to the string "d". Neat.

id | data

----+--------------------------------------

4 | {"a": 1, "b": {"c": "d", "e": true}}

Page 31: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

JSONTypeSELECT * FROM json_test WHERE data #> '{b,c}' = '"d"';

Give me objects where element b has a child object that has element c equal to the string "d". Neat.

id | data

----+--------------------------------------

4 | {"a": 1, "b": {"c": "d", "e": true}}

Page 32: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Demo

•github.com/hotsyk/djangopsqltest/jsonfield

Page 33: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Indexes

• Partial indexes

• Multicolumn indexes

Page 34: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Indexes>python manage.py makemigrations --empty yourappname

……

operations = [

migrations.RunSQL(

"CREATE UNIQUE INDEX IDX1 "

"ON Table1 (t1, t2) WHERE t2 IS NOT NULL"),

]

Page 35: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Pools

• Postgres database connections are expensive

• Django 1.6+ - builtin pool

• Django <1.6 - django-postgrespool, djorm-ext-pool, django-db-pool

Page 36: Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon Belarus

Questions

[email protected]

• twitter:@hotsyk

• github:hotsyk