103
Object-Relational Mapper

Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

  • Upload
    it-

  • View
    311

  • Download
    10

Embed Size (px)

DESCRIPTION

Алексей Малашкевич - Автор и разработчик Pony ORM / Pony ORM / Россия, Санкт-Петербург Александр Козловский - Автор и разработчик Pony ORM / Pony ORM / Россия, Санкт-Петербург Pony ORM - маппер, который позволяет работать с базой данных с помощью генераторных выражений языка Питон. С помощью такого подхода Pony позволяет формулировать очень компактные и понятные запросы, которые автоматически транслируются в оптимизированный SQL. Pony обладает графическим редактором ER диаграмм - удобным инструментом для создания и редактирования модели данных. В докладе разработчики Pony ORM расскажут про процесс перевода объектно-ориентированного запроса в запрос на языке SQL, о том какие оптимизации Pony применяет на каждом этапе обработки запроса, какие сложности стояли при разработке высокопроизводительного ORM и как Pony ORM облегчает и ускоряет разработку приложений. http://www.it-sobytie.ru/events/2040

Citation preview

Page 1: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Object-Relational Mapper

Page 2: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Что такое Pony ORM?

Page 3: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Что такое Pony ORM?

• Объектно-реляционный маппер

• Реализует паттерн Identity Map

• Транслирует генераторы в SQL

• Включает редактор ER диаграмм

• Автоматически оптимизирует SQL запросы

• Поддерживает Python 2.5 – 2.7

• Скоро появится поддержка Python 3

Page 4: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Демо (15 минут)

• Редактор ER диаграмм

• Создание БД и заполнение данными

• Работа с данными в интерактивном

режиме

Page 5: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM:

select(p for p in Person

if p.name.startswith('A') and p.tel is None

or p.dob.year < 2012

)

Способы построения запроса

Page 6: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Способы построения запроса

Django:

Person.objects.filter(

Q(name__startswith('A'), tel__isnull=True)

| Q(dob__year__lt=2012)

)

Page 7: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Способы построения запроса

SQLAlchemy:

session.query(Person).filter(

(Person.name.startswith('A')

& (Person.tel == None))

| (extract('year', Person.dob) < 2012)

)

Page 8: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

select(p for p in Person

if p.name.startswith('A') and p.tel is None

or p.dob.year < 2012

)

Person.objects.filter(

Q(name__startswith('A'), tel__isnull=True)

| Q(dob__year__lt=2012)

)

session.query(Person).filter(

(Person.name.startswith('A') & (Person.tel == None))

| (extract('year', Person.dob) < 2012)

)

Page 9: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Преимущества использования

синтаксиса генераторов:

• Несколько проще для запоминания

• Сложные запросы пишутся с меньшим

количеством «наворотов» (типа “Q”)

• Трансляция запросов в SQL

осуществляется гораздо быстрее!

(можно кешировать результат

трансляции и использовать

объект кода генератора как ключ)

Page 10: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Как Pony ORM транслирует

питоновские генераторы в SQL?

Page 11: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Трансляция генератора в SQL

1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST)

2. Трансляция AST в “абстрактный SQL” (представленный в виде списков)

3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL

Page 12: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Трансляция генератора в SQL

1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST)

2. Трансляция AST в “абстрактный SQL” (представленный в виде списков)

3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL

Page 13: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

• Используем паттерн Visitor

• Методы визитора соответствуют

операциям байткода

• Храним фрагменты восстановленного

AST на стеке

• Каждый метод или помещает на

вершину стека новый фрагмент AST,

или комбинирует имеющиеся

фрагменты

Page 14: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Page 15: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Page 16: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

> LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Page 17: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

> LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Name('a')

Page 18: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

> LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Name('a')

Page 19: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

> LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Name('b')

Name('a')

Page 20: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

> LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Name('b')

Name('a')

Page 21: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

> LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Getattr(Name('b'), 'c')

Name('a')

Декомпиляция байткода

Page 22: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

> BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Getattr(Name('b'), 'c')

Name('a')

Декомпиляция байткода

Page 23: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

> BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Add(Name('a'),

Getattr(Name('b'), 'c'))

Декомпиляция байткода

Page 24: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

> LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Add(Name('a'),

Getattr(Name('b'), 'c'))

Page 25: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

> LOAD_FAST x

LOAD_ATTR y

COMPARE_OP in

Стек

Name('x')

Add(Name('a'),

Getattr(Name('b'), 'c'))

Page 26: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

> LOAD_ATTR y

COMPARE_OP in

Стек

Name('x')

Add(Name('a'),

Getattr(Name('b'), 'c'))

Page 27: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

> LOAD_ATTR y

COMPARE_OP in

Стек

Getattr(Name('x'), 'y')

Add(Name('a'),

Getattr(Name('b'), 'c'))

Page 28: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

> COMPARE_OP in

Стек

Getattr(Name('x'), 'y')

Add(Name('a'),

Getattr(Name('b'), 'c'))

Page 29: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Декомпиляция байткода

(a + b.c) in x.y

LOAD_GLOBAL a

LOAD_FAST b

LOAD_ATTR c

BINARY_ADD

LOAD_FAST x

LOAD_ATTR y

> COMPARE_OP in

Стек

Compare('in',

Add(…), Getattr(…))

Page 30: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Абстрактное синтаксич. дерево (AST)

a

in

+

.c

b

.y

x

(a + b.c) in x.y

Page 31: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Трансляция генератора в SQL

1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST)

2. Трансляция AST в “абстрактный SQL” (представленный в виде списков)

3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL

Page 32: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Трансляция AST

• Используем паттерн Visitor

• Выполняем обход дерева вглубь

• Обрабатываем каждый узел на выходе

Page 33: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 34: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 35: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

a

in

+

.c

b

.y

x

(a + b.c) in x.y

Трансляция AST

Page 36: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

a

in

+

.c

b

.y

x

(a + b.c) in x.y

Трансляция AST

Page 37: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 38: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 39: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 40: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 41: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 42: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 43: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 44: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 45: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 46: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 47: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 48: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 49: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 50: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 51: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

• В какой SQL должно транслироваться?

• Зависит от типов переменных

• “+” может означать сложение чисел или конкатенацию строк – транслируется в +, CONCAT или ||

• “in” может транслироваться в подзапрос или в LIKE

(a + b.c) in x.y

Трансляция AST

Page 52: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

• (? + “b”.“c”) IN (SELECT …)

• CONCAT(?, “b”.“c”) IN (SELECT …)

• “x”.“y” LIKE ‘%’ || ? || “b”.“c” || ‘%’

(a + b.c) in x.y

Трансляция AST

Page 53: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

• Трансляция операции, такой как “+”, “in” или взятие атрибута, зависит от смысла подчиненных выражений

• Если класс транслятора сам выполняет весь необходимый анализ, логика транслятора становится чрезмерно сложной

• На помощь приходят монады

(a + b.c) in x.y

Трансляция AST

Page 54: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

• Инкапсулируют в себе результат анализа AST

• Умеют генерировать результат трансляции – “абстрактный SQL”

• Умеют комбинировать себя с другими монадами

• Обрабатывая узел AST, транслятор дает команду монадам нижележащих узлов скомбинировать себя и получить новую монаду

Монады

Page 55: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

• NumericParamMonad

• StringParamMonad

• ObjectIterMonad

• ObjectParamMonad

• NumericAttrMonad

• StringAttrMonad

• ObjectAttrMonad

• FuncMonad

• и т.д. …

Монады

Page 56: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 57: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 58: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

in

.y

x

+

a .c

b

Page 59: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада

Трансляция AST

in

.y

x

+

a .c

b

Page 60: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада

Трансляция AST

in

.y

x

+

a .c

b

Page 61: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада

Трансляция AST

in

.y

x

+

a .c

b

Page 62: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада

Трансляция AST

монада

in

.y

x

+

a .c

b

Page 63: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 64: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 65: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада

Трансляция AST

монада

in

.y

x

+

a .c

b

Page 66: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 67: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада

монада

Трансляция AST

монада

in

.y

x

+

a .c

b

Page 68: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 69: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 70: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 71: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада монада

монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 72: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада монада

монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 73: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

(a + b.c) in x.y

монада монада монада

монада

монада

Трансляция AST

монада

монада

in

.y

x

+

a .c

b

Page 74: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Aбстрактный SQL

(a + b.c) in x.y

['LIKE', ['COLUMN', 't1', 'y'], ['CONCAT', ['VALUE', '%'], ['PARAM', 'p1'], ['COLUMN', 't2', 'c'], ['VALUE', '%'] ] ] - Позволяет абстрагироваться от специфики конкретного диалекта

Page 75: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Трансляция генератора в SQL

1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST)

2. Трансляция AST в “абстрактный SQL” (представленный в виде списков)

3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL

Page 76: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Другие особенности Pony ORM

Page 77: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Другие особенности Pony ORM

• Автоматическая оптимизация запросов

• Identity Map

• Решение проблемы N+1

• Оптимистические транзакции

Page 78: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM

s1 = Student.object.get(pk=123)

print s1, s1.group.id

s2 = Student.object.get(pk=456)

print s2, s2.group.id

• Сколько SQL-запросов выполнится?

• Сколько объектов будет создано?

Page 79: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM

s1 = Student.object.get(pk=123)

print s1, s1.group.id

s2 = Student.object.get(pk=456)

print s2, s2.group.id

Page 80: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM

s1 = Student.object.get(pk=123)

print s1, s1.group.id

s2 = Student.object.get(pk=456)

print s2, s2.group.id

Student 123

Page 81: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM

s1 = Student.object.get(pk=123)

print s1, s1.group.id

s2 = Student.object.get(pk=456)

print s2, s2.group.id

Student 123 Group 1

Page 82: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM

s1 = Student.object.get(pk=123)

print s1, s1.group.id

s2 = Student.object.get(pk=456)

print s2, s2.group.id

Student 123

Student 456

Group 1

Page 83: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM

s1 = Student.object.get(pk=123)

print s1, s1.group.id

s2 = Student.object.get(pk=456)

print s2, s2.group.id

Student 123

Student 456

Group 1

Group 1

Page 84: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM

s1 = Student[123]

print s1, s1.group.id

s2 = Student[456]

print s2, s2.group.id

Page 85: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM – сиды, IdentityMap

s1 = Student[123]

print s1, s1.group.id

s2 = Student[456]

print s2, s2.group.id

Student 123

Group 1

Page 86: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM – сиды, IdentityMap

s1 = Student[123]

print s1, s1.group.id

s2 = Student[456]

print s2, s2.group.id

Student 123

Group 1

сид (seed)

Page 87: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM – сиды, IdentityMap

s1 = Student[123]

print s1, s1.group.id

s2 = Student[456]

print s2, s2.group.id

Student 123

Group 1

сид (seed)

Page 88: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM – сиды, IdentityMap

s1 = Student[123]

print s1, s1.group.id

s2 = Student[456]

print s2, s2.group.id

Student 123

Student 456

Group 1

сид (seed)

Page 89: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM – сиды, IdentityMap

s1 = Student[123]

print s1, s1.group.id

s2 = Student[456]

print s2, s2.group.id

Student 123

Student 456

Group 1

сид (seed)

Page 90: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Решение проблемы N+1 query

orders = select(o for o in Order

if o.price > 1000)

for o in orders:

print o.total_price, o.customer.name

SELECT o.id, o.total_price, o.customer_id, …

FROM “Order” o

WHERE o.price > 1000

Page 91: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Решение проблемы N+1 query

Order 1

Order 3

Order 4

Order 7

Order 9

Customer 1

Customer 4

Customer 7

Page 92: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Решение проблемы N+1 query

orders = select(o for o in Order if o.price > 1000)

for o in orders:

print o.total_price, o.customer.name

SELECT c.id, c.name, …

FROM “Customer” c

WHERE c.id IN (?, ?, ?)

Page 93: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Решение проблемы N+1 query

Order 1

Order 3

Order 4

Order 7

Order 9

Customer 1

Customer 4

Customer 7

Page 94: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM - транзакции

def transfer_money(id1, id2, amount):

account1 = Account.objects.get(pk=id1)

if account1.amount < amount:

raise ValueError(‘Not enough money!’)

account2 = Account.object.get(pk=id2)

account1.amount -= amount

account1.save()

account2.amount += amount

account2.save()

Page 95: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Django ORM - транзакции

@transaction.atomic

def transfer_money(id1, id2, amount):

account1 = Account.objects.get(pk=id1)

if account1.amount < amount:

raise ValueError(‘Not enough money!’)

account2 = Account.object.get(pk=id2)

account1.amount -= amount

account1.save()

account2.amount += amount

account2.save()

Page 96: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

@transaction.atomic

def transfer_money(id1, id2, amount):

account1 = Account.objects. \

select_for_update.get(pk=id1)

if account1.amount < amount:

raise ValueError(‘Not enough money!’)

account2 = Account.objects. \

select_for_update.get(pk=id2)

account1.amount -= amount

account1.save()

account2.amount += amount

account2.save()

Page 97: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM - транзакции

@db_session

def transfer_money(id1, id2, amount):

account1 = Account[id1]

if account1.amount < amount:

raise ValueError(‘Not enough money!’)

account1.amount -= amount

Account[id2].amount += amount

Page 98: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

db_session

• Pony автоматически отслеживает какие

объекты были изменены

• В момент выхода из db_session, если не

возникло исключений, происходит

сохранение всех измененных объектов

в рамках единой транзакции

• Пользователь не обязан сам вызывать

save для сохранения объектов

Page 99: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Оптимистические транзакции

• Pony отслеживает какие атрибуты

пользователь читал а какие изменял

• Если объект не был заблокирован в БД

в момент выборки, при сохранении

объекта Pony автоматически добавляет

проверки для оптимистических

блокировок

Page 100: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Оптимистические транзакции

UPDATE Account

SET amount = :new_value

WHERE id = :id

AND amount = :old_value

Page 101: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Pony ORM - транзакции

@db_session

def transfer_money(id1, id2, amount):

account1 = Account.get_for_update(id=id1)

if account1.amount < amount:

raise ValueError(‘Not enough money!’)

account1.amount -= amount

account2 = Account.get_for_update(id=id2)

account2.amount += amount

Page 102: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Особенности Pony ORM

• Использование генераторов и лямбд для формулирования запросов

• Автоматическая оптимизация запросов

• Identity Map

• Решение проблемы N+1

• Оптимистические транзакции

• Графический редактор ER-диаграмм

• В перспективе – поддержка NoSQL

Page 103: Pony ORM - маппер нового поколения (Алексей Малашкевич и Александр Козловский)

Заключение

• Сайт ponyorm.com

• Редактор editor.ponyorm.com

• Установка pip install pony==0.5-beta

Спасибо за внимание!