SlideShare une entreprise Scribd logo
1  sur  103
Télécharger pour lire hors ligne
Object-Relational Mapper
Что такое Pony ORM?
Что такое Pony ORM?
• Объектно-реляционный маппер
• Реализует паттерн Identity Map
• Транслирует генераторы в SQL
• Включает редактор ER диаграмм
• Автоматически оптимизирует SQL запросы
• Поддерживает Python 2.5 – 2.7
• Скоро появится поддержка Python 3
Демо (15 минут)
• Редактор ER диаграмм
• Создание БД и заполнение данными
• Работа с данными в интерактивном
режиме
Pony ORM:
select(p for p in Person
if p.name.startswith('A') and p.tel is None
or p.dob.year < 2012
)
Способы построения запроса
Способы построения запроса
Django:
Person.objects.filter(
Q(name__startswith('A'), tel__isnull=True)
| Q(dob__year__lt=2012)
)
Способы построения запроса
SQLAlchemy:
session.query(Person).filter(
(Person.name.startswith('A')
& (Person.tel == None))
| (extract('year', Person.dob) < 2012)
)
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)
)
Преимущества использования
синтаксиса генераторов:
• Несколько проще для запоминания
• Сложные запросы пишутся с меньшим
количеством «наворотов» (типа “Q”)
• Трансляция запросов в SQL
осуществляется гораздо быстрее!
(можно кешировать результат
трансляции и использовать
объект кода генератора как ключ)
Как Pony ORM транслирует
питоновские генераторы в SQL?
Трансляция генератора в SQL
1. Декомпиляция байткода,
восстановление абстрактного
синтаксического дерева (AST)
2. Трансляция AST в “абстрактный SQL”
(представленный в виде списков)
3. Трансляция “абстрактного SQL”
в конкретный диалект языка SQL
Трансляция генератора в SQL
1. Декомпиляция байткода,
восстановление абстрактного
синтаксического дерева (AST)
2. Трансляция AST в “абстрактный SQL”
(представленный в виде списков)
3. Трансляция “абстрактного SQL”
в конкретный диалект языка SQL
Декомпиляция байткода
• Используем паттерн Visitor
• Методы визитора соответствуют
операциям байткода
• Храним фрагменты восстановленного
AST на стеке
• Каждый метод или помещает на
вершину стека новый фрагмент AST,
или комбинирует имеющиеся
фрагменты
Декомпиляция байткода
(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
Декомпиляция байткода
(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
Стек
Декомпиляция байткода
(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
Стек
Декомпиляция байткода
(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')
Декомпиляция байткода
(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')
Декомпиляция байткода
(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')
Декомпиляция байткода
(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')
(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')
Декомпиляция байткода
(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')
Декомпиляция байткода
(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'))
Декомпиляция байткода
Декомпиляция байткода
(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'))
Декомпиляция байткода
(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'))
Декомпиляция байткода
(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'))
Декомпиляция байткода
(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'))
Декомпиляция байткода
(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'))
Декомпиляция байткода
(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(…))
Абстрактное синтаксич. дерево (AST)
a
in
+
.c
b
.y
x
(a + b.c) in x.y
Трансляция генератора в SQL
1. Декомпиляция байткода,
восстановление абстрактного
синтаксического дерева (AST)
2. Трансляция AST в “абстрактный SQL”
(представленный в виде списков)
3. Трансляция “абстрактного SQL”
в конкретный диалект языка SQL
Трансляция AST
• Используем паттерн Visitor
• Выполняем обход дерева вглубь
• Обрабатываем каждый узел на выходе
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
a
in
+
.c
b
.y
x
(a + b.c) in x.y
Трансляция AST
a
in
+
.c
b
.y
x
(a + b.c) in x.y
Трансляция AST
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
• В какой SQL должно транслироваться?
• Зависит от типов переменных
• “+” может означать сложение чисел или
конкатенацию строк – транслируется в +,
CONCAT или ||
• “in” может транслироваться в подзапрос
или в LIKE
(a + b.c) in x.y
Трансляция AST
• (? + “b”.“c”) IN (SELECT …)
• CONCAT(?, “b”.“c”) IN (SELECT …)
• “x”.“y” LIKE ‘%’ || ? || “b”.“c” || ‘%’
(a + b.c) in x.y
Трансляция AST
• Трансляция операции, такой как “+”, “in”
или взятие атрибута, зависит от смысла
подчиненных выражений
• Если класс транслятора сам выполняет
весь необходимый анализ, логика
транслятора становится чрезмерно
сложной
• На помощь приходят монады
(a + b.c) in x.y
Трансляция AST
• Инкапсулируют в себе результат
анализа AST
• Умеют генерировать результат
трансляции – “абстрактный SQL”
• Умеют комбинировать себя с другими
монадами
• Обрабатывая узел AST, транслятор дает
команду монадам нижележащих узлов
скомбинировать себя и получить новую
монаду
Монады
• NumericParamMonad
• StringParamMonad
• ObjectIterMonad
• ObjectParamMonad
• NumericAttrMonad
• StringAttrMonad
• ObjectAttrMonad
• FuncMonad
• и т.д. …
Монады
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада
Трансляция AST
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада
Трансляция AST
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада
Трансляция AST
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада
монада
Трансляция AST
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада монада
монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада монада
монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
(a + b.c) in x.y
монада монада монада
монада
монада
Трансляция AST
монада
монада
in
.y
x
+
a .c
b
Aбстрактный SQL
(a + b.c) in x.y
['LIKE', ['COLUMN', 't1', 'y'],
['CONCAT',
['VALUE', '%'], ['PARAM', 'p1'],
['COLUMN', 't2', 'c'], ['VALUE', '%']
]
]
- Позволяет абстрагироваться от специфики
конкретного диалекта
Трансляция генератора в SQL
1. Декомпиляция байткода,
восстановление абстрактного
синтаксического дерева (AST)
2. Трансляция AST в “абстрактный SQL”
(представленный в виде списков)
3. Трансляция “абстрактного SQL”
в конкретный диалект языка SQL
Другие особенности Pony ORM
Другие особенности Pony ORM
• Автоматическая оптимизация запросов
• Identity Map
• Решение проблемы N+1
• Оптимистические транзакции
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-запросов выполнится?
• Сколько объектов будет создано?
Django ORM
s1 = Student.object.get(pk=123)
print s1, s1.group.id
s2 = Student.object.get(pk=456)
print s2, s2.group.id
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
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
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
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
Pony ORM
s1 = Student[123]
print s1, s1.group.id
s2 = Student[456]
print s2, s2.group.id
Pony ORM – сиды, IdentityMap
s1 = Student[123]
print s1, s1.group.id
s2 = Student[456]
print s2, s2.group.id
Student 123
Group 1
Pony ORM – сиды, IdentityMap
s1 = Student[123]
print s1, s1.group.id
s2 = Student[456]
print s2, s2.group.id
Student 123
Group 1
сид (seed)
Pony ORM – сиды, IdentityMap
s1 = Student[123]
print s1, s1.group.id
s2 = Student[456]
print s2, s2.group.id
Student 123
Group 1
сид (seed)
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)
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)
Решение проблемы 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
Решение проблемы N+1 query
Order 1
Order 3
Order 4
Order 7
Order 9
Customer 1
Customer 4
Customer 7
Решение проблемы 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 (?, ?, ?)
Решение проблемы N+1 query
Order 1
Order 3
Order 4
Order 7
Order 9
Customer 1
Customer 4
Customer 7
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()
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()
@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()
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
db_session
• Pony автоматически отслеживает какие
объекты были изменены
• В момент выхода из db_session, если не
возникло исключений, происходит
сохранение всех измененных объектов
в рамках единой транзакции
• Пользователь не обязан сам вызывать
save для сохранения объектов
Оптимистические транзакции
• Pony отслеживает какие атрибуты
пользователь читал а какие изменял
• Если объект не был заблокирован в БД
в момент выборки, при сохранении
объекта Pony автоматически добавляет
проверки для оптимистических
блокировок
Оптимистические транзакции
UPDATE Account
SET amount = :new_value
WHERE id = :id
AND amount = :old_value
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
Особенности Pony ORM
• Использование генераторов и лямбд
для формулирования запросов
• Автоматическая оптимизация запросов
• Identity Map
• Решение проблемы N+1
• Оптимистические транзакции
• Графический редактор ER-диаграмм
• В перспективе – поддержка NoSQL
Заключение
• Сайт ponyorm.com
• Редактор editor.ponyorm.com
• Установка pip install pony==0.5-beta
Спасибо за внимание!

Contenu connexe

Tendances

Highload: специализированные высокопроизводительные индексы
Highload: специализированные высокопроизводительные индексыHighload: специализированные высокопроизводительные индексы
Highload: специализированные высокопроизводительные индексыPavel Egorov
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupMail.ru Group
 
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)Mikhail Kurnosov
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаMikhail Kurnosov
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Yandex
 
Лекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимостиЛекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимостиMikhail Kurnosov
 
Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Mikhail Kurnosov
 
Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Mikhail Kurnosov
 
DSLs in Lisp and Clojure
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and ClojureVasil Remeniuk
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Mikhail Kurnosov
 
User Defined Materials in LS-DYNA
User Defined Materials in LS-DYNAUser Defined Materials in LS-DYNA
User Defined Materials in LS-DYNAYury Novozhilov
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиMikhail Kurnosov
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...Ontico
 
Groovy и Grails. Быстро и обо всём
Groovy и Grails. Быстро и обо всёмGroovy и Grails. Быстро и обо всём
Groovy и Grails. Быстро и обо всёмRuslan Balkin
 
JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...
JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...
JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...JSFestUA
 
О-символика
О-символикаО-символика
О-символикаDEVTYPE
 
Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"
Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"
Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"Nikolay Grebenshikov
 
Структуры данных в JavaScript | Odessa Frontend Meetup #13
Структуры данных в JavaScript | Odessa Frontend Meetup #13Структуры данных в JavaScript | Odessa Frontend Meetup #13
Структуры данных в JavaScript | Odessa Frontend Meetup #13OdessaFrontend
 

Tendances (20)

Highload: специализированные высокопроизводительные индексы
Highload: специализированные высокопроизводительные индексыHighload: специализированные высокопроизводительные индексы
Highload: специализированные высокопроизводительные индексы
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
 
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
Лекция 7: Очереди с приоритетами. Бинарные кучи (пирамиды)
 
Лекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировкаЛекция 7. Бинарные кучи. Пирамидальная сортировка
Лекция 7. Бинарные кучи. Пирамидальная сортировка
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
Лекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимостиЛекция 10: Графы. Остовные деревья минимальной стоимости
Лекция 10: Графы. Остовные деревья минимальной стоимости
 
Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)Лекция 7. Стандарт OpenMP (подолжение)
Лекция 7. Стандарт OpenMP (подолжение)
 
Векторизация кода (семинар 3)
Векторизация кода (семинар 3)Векторизация кода (семинар 3)
Векторизация кода (семинар 3)
 
DSLs in Lisp and Clojure
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and Clojure
 
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
Лекция 6. Фибоначчиевы кучи (Fibonacci heaps)
 
User Defined Materials in LS-DYNA
User Defined Materials in LS-DYNAUser Defined Materials in LS-DYNA
User Defined Materials in LS-DYNA
 
Лекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимостиЛекция 10. Графы. Остовные деревья минимальной стоимости
Лекция 10. Графы. Остовные деревья минимальной стоимости
 
Продолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложенийПродолжаем говорить о микрооптимизациях .NET-приложений
Продолжаем говорить о микрооптимизациях .NET-приложений
 
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
 
введение в Gpu
введение в Gpuвведение в Gpu
введение в Gpu
 
Groovy и Grails. Быстро и обо всём
Groovy и Grails. Быстро и обо всёмGroovy и Grails. Быстро и обо всём
Groovy и Grails. Быстро и обо всём
 
JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...
JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...
JS Fest 2019/Autumn. Adam Leos. So why do you need to know Algorithms and Dat...
 
О-символика
О-символикаО-символика
О-символика
 
Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"
Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"
Лекция №16. Поиск подстрок. Предмет "Структуры и алгоритмы обработки данных"
 
Структуры данных в JavaScript | Odessa Frontend Meetup #13
Структуры данных в JavaScript | Odessa Frontend Meetup #13Структуры данных в JavaScript | Odessa Frontend Meetup #13
Структуры данных в JavaScript | Odessa Frontend Meetup #13
 

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

Монады для барабанщиков. Антон Холомьёв
Монады для барабанщиков. Антон ХоломьёвМонады для барабанщиков. Антон Холомьёв
Монады для барабанщиков. Антон ХоломьёвЮрий Сыровецкий
 
A System of Deductive Verification of Predicate Programs
A System of Deductive Verification of Predicate ProgramsA System of Deductive Verification of Predicate Programs
A System of Deductive Verification of Predicate ProgramsIosif Itkin
 
Функциональное программирование - Александр Алексеев
Функциональное программирование - Александр АлексеевФункциональное программирование - Александр Алексеев
Функциональное программирование - Александр АлексеевAleksander Alekseev
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Встраивание языка в строковой интерполятор
Встраивание языка в строковой интерполяторВстраивание языка в строковой интерполятор
Встраивание языка в строковой интерполяторMichael Limansky
 
Matemat526
Matemat526Matemat526
Matemat526tesla21
 
Интерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадИнтерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадZheka Kozlov
 

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

Java 8 puzzlers
Java 8 puzzlersJava 8 puzzlers
Java 8 puzzlers
 
Монады для барабанщиков. Антон Холомьёв
Монады для барабанщиков. Антон ХоломьёвМонады для барабанщиков. Антон Холомьёв
Монады для барабанщиков. Антон Холомьёв
 
A System of Deductive Verification of Predicate Programs
A System of Deductive Verification of Predicate ProgramsA System of Deductive Verification of Predicate Programs
A System of Deductive Verification of Predicate Programs
 
Функциональное программирование - Александр Алексеев
Функциональное программирование - Александр АлексеевФункциональное программирование - Александр Алексеев
Функциональное программирование - Александр Алексеев
 
лекция18
лекция18лекция18
лекция18
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Встраивание языка в строковой интерполятор
Встраивание языка в строковой интерполяторВстраивание языка в строковой интерполятор
Встраивание языка в строковой интерполятор
 
Matemat526
Matemat526Matemat526
Matemat526
 
20110227 csseminar alvor_breslav
20110227 csseminar alvor_breslav20110227 csseminar alvor_breslav
20110227 csseminar alvor_breslav
 
Интерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монадИнтерпретирование языков с помощью Free-монад
Интерпретирование языков с помощью Free-монад
 

Plus de IT-Доминанта

Алексей Федоров: Количественные исследования в HR
Алексей Федоров: Количественные исследования в HRАлексей Федоров: Количественные исследования в HR
Алексей Федоров: Количественные исследования в HRIT-Доминанта
 
Рекрутеры не волшебники или Почему клиенты тоже плачут?
Рекрутеры не волшебники или Почему клиенты тоже плачут?Рекрутеры не волшебники или Почему клиенты тоже плачут?
Рекрутеры не волшебники или Почему клиенты тоже плачут?IT-Доминанта
 
Конкуренция городов среди ИТ-специалистов
Конкуренция городов среди ИТ-специалистовКонкуренция городов среди ИТ-специалистов
Конкуренция городов среди ИТ-специалистовIT-Доминанта
 
Волшебная формула найма
Волшебная формула наймаВолшебная формула найма
Волшебная формула наймаIT-Доминанта
 
Рекрутинг и коммьюнити билдинг за МКАДом: миссия выполнима
Рекрутинг и коммьюнити билдинг за МКАДом: миссия выполнимаРекрутинг и коммьюнити билдинг за МКАДом: миссия выполнима
Рекрутинг и коммьюнити билдинг за МКАДом: миссия выполнимаIT-Доминанта
 
Как продать вакансию техническому специалисту?
Как продать вакансию техническому специалисту?Как продать вакансию техническому специалисту?
Как продать вакансию техническому специалисту?IT-Доминанта
 
Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"
Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"
Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"IT-Доминанта
 
Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...
Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...
Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...IT-Доминанта
 
6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообще
6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообще6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообще
6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообщеIT-Доминанта
 
Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...
Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...
Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...IT-Доминанта
 
Повышаем эффективность и прозрачность HR, сокращаем расходы
Повышаем эффективность и прозрачность HR, сокращаем расходыПовышаем эффективность и прозрачность HR, сокращаем расходы
Повышаем эффективность и прозрачность HR, сокращаем расходыIT-Доминанта
 
Премирование для IT – фикция или работающий инструмент?
Премирование для IT – фикция или работающий инструмент?Премирование для IT – фикция или работающий инструмент?
Премирование для IT – фикция или работающий инструмент?IT-Доминанта
 
Простые непростые истины бюджетирования или сколько стоит управление персоналом?
Простые непростые истины бюджетирования или сколько стоит управление персоналом?Простые непростые истины бюджетирования или сколько стоит управление персоналом?
Простые непростые истины бюджетирования или сколько стоит управление персоналом?IT-Доминанта
 
Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)
Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)
Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)IT-Доминанта
 
О геймификации серьезно: опыт Veeam (от проблемы до внедрения)
О геймификации серьезно: опыт Veeam (от проблемы до внедрения)О геймификации серьезно: опыт Veeam (от проблемы до внедрения)
О геймификации серьезно: опыт Veeam (от проблемы до внедрения)IT-Доминанта
 
дарья кирпо для найти ответ - публикация
дарья кирпо   для найти ответ  - публикациядарья кирпо   для найти ответ  - публикация
дарья кирпо для найти ответ - публикацияIT-Доминанта
 
HR брендинг: позиционирование компании на рынке труда (часть 1)
HR брендинг: позиционирование компании на рынке труда (часть 1)HR брендинг: позиционирование компании на рынке труда (часть 1)
HR брендинг: позиционирование компании на рынке труда (часть 1)IT-Доминанта
 

Plus de IT-Доминанта (20)

Алексей Федоров: Количественные исследования в HR
Алексей Федоров: Количественные исследования в HRАлексей Федоров: Количественные исследования в HR
Алексей Федоров: Количественные исследования в HR
 
Рекрутеры не волшебники или Почему клиенты тоже плачут?
Рекрутеры не волшебники или Почему клиенты тоже плачут?Рекрутеры не волшебники или Почему клиенты тоже плачут?
Рекрутеры не волшебники или Почему клиенты тоже плачут?
 
Soft skills matrix for HR manager
Soft skills matrix for HR managerSoft skills matrix for HR manager
Soft skills matrix for HR manager
 
Конкуренция городов среди ИТ-специалистов
Конкуренция городов среди ИТ-специалистовКонкуренция городов среди ИТ-специалистов
Конкуренция городов среди ИТ-специалистов
 
Волшебная формула найма
Волшебная формула наймаВолшебная формула найма
Волшебная формула найма
 
Рекрутинг и коммьюнити билдинг за МКАДом: миссия выполнима
Рекрутинг и коммьюнити билдинг за МКАДом: миссия выполнимаРекрутинг и коммьюнити билдинг за МКАДом: миссия выполнима
Рекрутинг и коммьюнити билдинг за МКАДом: миссия выполнима
 
Как продать вакансию техническому специалисту?
Как продать вакансию техническому специалисту?Как продать вакансию техническому специалисту?
Как продать вакансию техническому специалисту?
 
Для спикера Piter Py #3
Для спикера Piter Py #3Для спикера Piter Py #3
Для спикера Piter Py #3
 
IT HR Meetup 24 (Faina Lerner)
IT HR Meetup 24 (Faina Lerner)IT HR Meetup 24 (Faina Lerner)
IT HR Meetup 24 (Faina Lerner)
 
Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"
Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"
Дмитрий Кончаленков "Особенности маркетинга IT продуктов в социальных сетях"
 
Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...
Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...
Андрей Маркин "Основы маркетинга (продвижения) IT продуктов в поисковых и мед...
 
6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообще
6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообще6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообще
6 самых неприличных поз HR-брендинга и стоит ли им заниматься вообще
 
Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...
Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...
Цифровой лайфхак, или как посчитать счастье сотрудников: сбор, анализ и предс...
 
Повышаем эффективность и прозрачность HR, сокращаем расходы
Повышаем эффективность и прозрачность HR, сокращаем расходыПовышаем эффективность и прозрачность HR, сокращаем расходы
Повышаем эффективность и прозрачность HR, сокращаем расходы
 
Премирование для IT – фикция или работающий инструмент?
Премирование для IT – фикция или работающий инструмент?Премирование для IT – фикция или работающий инструмент?
Премирование для IT – фикция или работающий инструмент?
 
Простые непростые истины бюджетирования или сколько стоит управление персоналом?
Простые непростые истины бюджетирования или сколько стоит управление персоналом?Простые непростые истины бюджетирования или сколько стоит управление персоналом?
Простые непростые истины бюджетирования или сколько стоит управление персоналом?
 
Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)
Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)
Повышают ли ретроспективы проектов результативность команд? (Дмитрий Лазареd)
 
О геймификации серьезно: опыт Veeam (от проблемы до внедрения)
О геймификации серьезно: опыт Veeam (от проблемы до внедрения)О геймификации серьезно: опыт Veeam (от проблемы до внедрения)
О геймификации серьезно: опыт Veeam (от проблемы до внедрения)
 
дарья кирпо для найти ответ - публикация
дарья кирпо   для найти ответ  - публикациядарья кирпо   для найти ответ  - публикация
дарья кирпо для найти ответ - публикация
 
HR брендинг: позиционирование компании на рынке труда (часть 1)
HR брендинг: позиционирование компании на рынке труда (часть 1)HR брендинг: позиционирование компании на рынке труда (часть 1)
HR брендинг: позиционирование компании на рынке труда (часть 1)
 

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

  • 3. Что такое Pony ORM? • Объектно-реляционный маппер • Реализует паттерн Identity Map • Транслирует генераторы в SQL • Включает редактор ER диаграмм • Автоматически оптимизирует SQL запросы • Поддерживает Python 2.5 – 2.7 • Скоро появится поддержка Python 3
  • 4. Демо (15 минут) • Редактор ER диаграмм • Создание БД и заполнение данными • Работа с данными в интерактивном режиме
  • 5. Pony ORM: select(p for p in Person if p.name.startswith('A') and p.tel is None or p.dob.year < 2012 ) Способы построения запроса
  • 8. 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) )
  • 9. Преимущества использования синтаксиса генераторов: • Несколько проще для запоминания • Сложные запросы пишутся с меньшим количеством «наворотов» (типа “Q”) • Трансляция запросов в SQL осуществляется гораздо быстрее! (можно кешировать результат трансляции и использовать объект кода генератора как ключ)
  • 10. Как Pony ORM транслирует питоновские генераторы в SQL?
  • 11. Трансляция генератора в SQL 1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST) 2. Трансляция AST в “абстрактный SQL” (представленный в виде списков) 3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL
  • 12. Трансляция генератора в SQL 1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST) 2. Трансляция AST в “абстрактный SQL” (представленный в виде списков) 3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL
  • 13. Декомпиляция байткода • Используем паттерн Visitor • Методы визитора соответствуют операциям байткода • Храним фрагменты восстановленного AST на стеке • Каждый метод или помещает на вершину стека новый фрагмент AST, или комбинирует имеющиеся фрагменты
  • 14. Декомпиляция байткода (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
  • 15. Декомпиляция байткода (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 Стек
  • 16. Декомпиляция байткода (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 Стек
  • 17. Декомпиляция байткода (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')
  • 18. Декомпиляция байткода (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')
  • 19. Декомпиляция байткода (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')
  • 20. Декомпиляция байткода (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')
  • 21. (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') Декомпиляция байткода
  • 22. (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') Декомпиляция байткода
  • 23. (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')) Декомпиляция байткода
  • 24. Декомпиляция байткода (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'))
  • 25. Декомпиляция байткода (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'))
  • 26. Декомпиляция байткода (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'))
  • 27. Декомпиляция байткода (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'))
  • 28. Декомпиляция байткода (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'))
  • 29. Декомпиляция байткода (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(…))
  • 30. Абстрактное синтаксич. дерево (AST) a in + .c b .y x (a + b.c) in x.y
  • 31. Трансляция генератора в SQL 1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST) 2. Трансляция AST в “абстрактный SQL” (представленный в виде списков) 3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL
  • 32. Трансляция AST • Используем паттерн Visitor • Выполняем обход дерева вглубь • Обрабатываем каждый узел на выходе
  • 33. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 34. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 35. a in + .c b .y x (a + b.c) in x.y Трансляция AST
  • 36. a in + .c b .y x (a + b.c) in x.y Трансляция AST
  • 37. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 38. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 39. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 40. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 41. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 42. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 43. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 44. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 45. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 46. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 47. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 48. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 49. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 50. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 51. • В какой SQL должно транслироваться? • Зависит от типов переменных • “+” может означать сложение чисел или конкатенацию строк – транслируется в +, CONCAT или || • “in” может транслироваться в подзапрос или в LIKE (a + b.c) in x.y Трансляция AST
  • 52. • (? + “b”.“c”) IN (SELECT …) • CONCAT(?, “b”.“c”) IN (SELECT …) • “x”.“y” LIKE ‘%’ || ? || “b”.“c” || ‘%’ (a + b.c) in x.y Трансляция AST
  • 53. • Трансляция операции, такой как “+”, “in” или взятие атрибута, зависит от смысла подчиненных выражений • Если класс транслятора сам выполняет весь необходимый анализ, логика транслятора становится чрезмерно сложной • На помощь приходят монады (a + b.c) in x.y Трансляция AST
  • 54. • Инкапсулируют в себе результат анализа AST • Умеют генерировать результат трансляции – “абстрактный SQL” • Умеют комбинировать себя с другими монадами • Обрабатывая узел AST, транслятор дает команду монадам нижележащих узлов скомбинировать себя и получить новую монаду Монады
  • 55. • NumericParamMonad • StringParamMonad • ObjectIterMonad • ObjectParamMonad • NumericAttrMonad • StringAttrMonad • ObjectAttrMonad • FuncMonad • и т.д. … Монады
  • 56. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 57. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 58. (a + b.c) in x.y Трансляция AST in .y x + a .c b
  • 59. (a + b.c) in x.y монада Трансляция AST in .y x + a .c b
  • 60. (a + b.c) in x.y монада Трансляция AST in .y x + a .c b
  • 61. (a + b.c) in x.y монада Трансляция AST in .y x + a .c b
  • 62. (a + b.c) in x.y монада Трансляция AST монада in .y x + a .c b
  • 63. (a + b.c) in x.y Трансляция AST монада монада in .y x + a .c b
  • 64. (a + b.c) in x.y монада Трансляция AST монада монада in .y x + a .c b
  • 65. (a + b.c) in x.y монада монада Трансляция AST монада in .y x + a .c b
  • 66. (a + b.c) in x.y монада монада Трансляция AST монада монада in .y x + a .c b
  • 67. (a + b.c) in x.y монада монада монада Трансляция AST монада in .y x + a .c b
  • 68. (a + b.c) in x.y монада монада Трансляция AST монада монада in .y x + a .c b
  • 69. (a + b.c) in x.y монада монада монада Трансляция AST монада монада in .y x + a .c b
  • 70. (a + b.c) in x.y монада монада монада Трансляция AST монада монада in .y x + a .c b
  • 71. (a + b.c) in x.y монада монада монада монада Трансляция AST монада монада in .y x + a .c b
  • 72. (a + b.c) in x.y монада монада монада монада Трансляция AST монада монада in .y x + a .c b
  • 73. (a + b.c) in x.y монада монада монада монада монада Трансляция AST монада монада in .y x + a .c b
  • 74. Aбстрактный SQL (a + b.c) in x.y ['LIKE', ['COLUMN', 't1', 'y'], ['CONCAT', ['VALUE', '%'], ['PARAM', 'p1'], ['COLUMN', 't2', 'c'], ['VALUE', '%'] ] ] - Позволяет абстрагироваться от специфики конкретного диалекта
  • 75. Трансляция генератора в SQL 1. Декомпиляция байткода, восстановление абстрактного синтаксического дерева (AST) 2. Трансляция AST в “абстрактный SQL” (представленный в виде списков) 3. Трансляция “абстрактного SQL” в конкретный диалект языка SQL
  • 77. Другие особенности Pony ORM • Автоматическая оптимизация запросов • Identity Map • Решение проблемы N+1 • Оптимистические транзакции
  • 78. 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-запросов выполнится? • Сколько объектов будет создано?
  • 79. Django ORM s1 = Student.object.get(pk=123) print s1, s1.group.id s2 = Student.object.get(pk=456) print s2, s2.group.id
  • 80. 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
  • 81. 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
  • 82. 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
  • 83. 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
  • 84. Pony ORM s1 = Student[123] print s1, s1.group.id s2 = Student[456] print s2, s2.group.id
  • 85. Pony ORM – сиды, IdentityMap s1 = Student[123] print s1, s1.group.id s2 = Student[456] print s2, s2.group.id Student 123 Group 1
  • 86. Pony ORM – сиды, IdentityMap s1 = Student[123] print s1, s1.group.id s2 = Student[456] print s2, s2.group.id Student 123 Group 1 сид (seed)
  • 87. Pony ORM – сиды, IdentityMap s1 = Student[123] print s1, s1.group.id s2 = Student[456] print s2, s2.group.id Student 123 Group 1 сид (seed)
  • 88. 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)
  • 89. 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)
  • 90. Решение проблемы 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
  • 91. Решение проблемы N+1 query Order 1 Order 3 Order 4 Order 7 Order 9 Customer 1 Customer 4 Customer 7
  • 92. Решение проблемы 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 (?, ?, ?)
  • 93. Решение проблемы N+1 query Order 1 Order 3 Order 4 Order 7 Order 9 Customer 1 Customer 4 Customer 7
  • 94. 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()
  • 95. 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()
  • 96. @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()
  • 97. 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
  • 98. db_session • Pony автоматически отслеживает какие объекты были изменены • В момент выхода из db_session, если не возникло исключений, происходит сохранение всех измененных объектов в рамках единой транзакции • Пользователь не обязан сам вызывать save для сохранения объектов
  • 99. Оптимистические транзакции • Pony отслеживает какие атрибуты пользователь читал а какие изменял • Если объект не был заблокирован в БД в момент выборки, при сохранении объекта Pony автоматически добавляет проверки для оптимистических блокировок
  • 100. Оптимистические транзакции UPDATE Account SET amount = :new_value WHERE id = :id AND amount = :old_value
  • 101. 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
  • 102. Особенности Pony ORM • Использование генераторов и лямбд для формулирования запросов • Автоматическая оптимизация запросов • Identity Map • Решение проблемы N+1 • Оптимистические транзакции • Графический редактор ER-диаграмм • В перспективе – поддержка NoSQL
  • 103. Заключение • Сайт ponyorm.com • Редактор editor.ponyorm.com • Установка pip install pony==0.5-beta Спасибо за внимание!