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

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

Embed Size (px)

Citation preview

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