Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

Доклад с Moscow Python Conf 2016 (http://conf.python.ru)
Видео: https://conf.python.ru/pony-orm-migracii-mega-anons/

Мы занимаемся разработкой маппера Pony ORM в течение нескольких лет. За это время нам удалось разработать библиотеку, которую используют разработчики во всем мире. Помимо работы над Pony ORM, наша компания разрабатывает веб проекты, в которых мы используем наш маппер. Один из примеров - https://fineartbiblio.com
За последние несколько лет Pony ORM зарекомендовала себя как удобная библиотека для построения современных веб приложений. Единственное, чего не хватало Пони для полноценного использования в продакшене, это инструмента миграций, позволяющего изменять таблицы базы данных при изменении описания сущностей.
В нашем выступлении мы расскажем о том как мы делали инструмент миграций, с какими сложностями столкнулись, и чем наш инструмент отличается от того, что предоставляют другие мапперы.
Но это не единственная новость, которой мы хотим поделиться с нашими пользователями. Мы подготовили для вас мегаанонс, о котором вы узнаете во время выступления.

Moscow Python Meetup

October 12, 2016
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Что такое Pony ORM? Pony ORM - это объектно-реляционный маппер

    на Питоне • Простой и понятный синтаксис запросов select(c for c in Customer if sum(c.orders.price) > 1000) • Высокая производительность, автоматическая оптимизация запросов select(c for c in Customer if sum(o.price for o in c.orders) > 1000)
  2. Текущее состояние Pony ORM • Проект активно развивается в течение

    10 лет • Много очень положительных отзывов 
 от пользователей • Основные пользователи: • Америка • Россия • Индия • Европа • Китай • Бразилия
  3. Отзывы пользователей Pony “Активно используем Pony ORM в наших проектах

    уже несколько лет. Очень легко писать бизнес логику приложения - запросы интуитивно понятны. Суб-коллекции - это просто подарок! Особенно с сортировкой и лифтингом атрибутов!” Марк Коренберг СТО, ideco.ru
  4. Отзывы пользователей Pony “В PonyORM я ценю высокую скорость работы,

    наличие DSL, который позволяет писать более понятный код. Это была кстати одна из причин того что я начал искать альтернативу SQLAlchemy.“ Анатолий Шипицин Разработчик “It's certainly the most intui~ve & Pythonis~c approach to querying databases and is very similar to LINQ in that aspect.” Omer Katz Very passionate soˆware developer hŠp://omerkatz.com
  5. Отзывы пользователей Pony “At this point in ~me, I wouldn't

    even consider using a different ORM for projects.” Nicholas Brochu Maker of digital and physical things. @nbrochu “I use pony in produc~on on AMZShark.com. It allows me to create webapps much faster than any other ORM I've tried, and produces sensible, performant SQL both in produc~on with Postgres and when tes~ng with SQLite.” MaŠhew Bell AMZshark.com
  6. session.query(Product).filter( (Product.name.startswith('A') & (Product.image == None)) | (extract('year', Product.added) <

    2014)) Сравнение синтаксиса запросов Product.objects.filter( Q(name__startswith='A', image__isnull=True) | Q(added__year__lt=2014)) select(p for p in Product if p.name.startswith('A') and p.image is None or p.added.year < 2014) Pony Django SQLAlchemy
  7. Django ORM, Active Record s1 = Student.objects.get(pk=123) print(s1.name, s1.group.id) s2

    = Student.objects.get(pk=456) print(s2.name, s2.group.id) Student 123 Student 456 Group 1 Group 1
  8. Pony ORM, IdentityMap s1 = Student[123] print(s1.name, s1.group.id) s2 =

    Student[456] print(s2.name, s2.group.id) Student 123 Student 456 Group 1
  9. Другие преимущества PonyORM • Лифтинг атрибутов • Автоматическая оптимизация запросов

    • Решение проблемы “N+1 query” • Оптимистические транзакции • Множественное наследование сущностей • Отсутствие проблемы “срез объекта до базового класса” • Умное кеширование • Четкие сообщения об ошибках
  10. Поддержка database JSON • Лучшее из двух миров - SQL

    + noSQL • Поддерживается в PostgreSQL, SQLite, MySQL, Oracle • Использует эффективный binary JSON, где он есть • Поддержка JSON в запросах!
  11. Использование database JSON from pony.orm import * db = Database()

    class Product(db.En~ty): id = PrimaryKey(int, auto=True) name = Required(str) info = Required(Json)
  12. Использование database JSON p = Product(name='Samsung Galaxy Note7', info={ 'display':

    { 'size': 5.7, }, 'baŠery': 3500, 'exploding': True, 'SD card slot': True 'colors': ['Black', 'Grey', 'Gold'], })
  13. JSON атрибут в запросах x = 2048 select(p for p

    in Product if p.info['display']['resolu~on'][0] >= x) select(p for p in Product if 'Black' in p.info['colors'])
  14. PostgreSQL select(p for p in Product if p.info['display']['resolu~on'][0] >= x)


    
 SELECT "p"."id", "p"."name", "p"."info" FROM "product" "p" WHERE ("p"."info" #>> '{display,resolu~on,0}')::integer >= %(p1)s
  15. MySQL select(p for p in Product if p.info['display']['resolu~on'][0] >= x)


    
 SELECT `p`.`id`, `p`.`name`, `p`.`info`, `p`.`tags` FROM `product` `p` WHERE CAST(
 json_extract(`p`.`info`, '$.display.resolu~on[0]') AS SIGNED
 ) >= %s
  16. SQLite select(p for p in Product if p.info['display']['resolu~on'][0] >= x)


    SELECT "p"."id", "p"."name", "p"."info", "p"."tags" FROM "Product" "p" WHERE json_extract("p"."info", '$.display.resolu~on[0]') >= ?
  17. Oracle select(p for p in Product if p.info['display']['resolu~on'][0] >= x)


    SELECT "p"."ID", "p"."NAME", "p"."INFO", "p"."TAGS" FROM "PRODUCT" "p" WHERE JSON_VALUE( "p"."INFO", '$.display.resolu~on[0]' RETURNING NUMBER
 ) >= :p1
  18. Миграции • Отличия от других ORM • Django • SQLAlchemy

    Alembic • Внутренняя реализация • Пример использования
  19. Миграции в Django from django.db import migrations, models
 
 class

    Migration(migrations.Migration):
 
 dependencies = [
 ("migrations", "0001_initial")
 ]
 
 operations = [
 migrations.AddField("Person", "age",
 models.IntegerField(default=0)),
 ]
  20. Версии диаграммы/схемы Version1 Schema1 Table Column1 Column2 Diagram1 Entity Attribute1

    Attribute2 Version2 S2 Table Column1 Column2 D2 Entity Attribute1 Attribute2
  21. Интерфейс командной строки python -m pony.migrate make Создает новый файл

    миграции python -m pony.migrate apply Применяет миграции к базе python -m pony.migrate sql Выводит SQL который будет применен
  22. Примеры файлов миграций # 0001_initial.py
 
 from pony import orm


    
 dependencies = []
 
 def define_entities(db):
 class Person(db.Entity):
 name = orm.Required(str)

  23. Примеры файлов миграций # 0002_20161013_0922.py
 
 from pony import orm


    
 dependencies = ["0001_initial"]
 
 def define_entities(db):
 class Person(db.Entity):
 name = orm.Required(str)
 age = orm.Optional(int)
  24. Примеры файлов миграций # 0002_20161013_1015.py
 
 from pony import orm


    
 dependencies = ["0001_initial"]
 
 def define_entities(db):
 class Person(db.Entity):
 name = orm.Required(str)
 tel = orm.Optional(str)
  25. Примеры файлов миграций # 0003_20161013_1140.py
 
 from pony import orm


    
 dependencies = ["0002_20161013_0922",
 "0002_20161013_1015"]
 
 def define_entities(db):
 class Person(db.Entity):
 name = orm.Required(str)
 age = orm.Optional(int)
 tel = orm.Optional(str)
  26. Примеры файлов миграций # 0004_20161013_1140.py
 
 from pony import orm


    
 dependencies = ["0003_20161013_1140"]
 
 renames = {"Person.tel": "Person.phone"}
 
 def define_entities(db):
 class Person(db.Entity):
 name = orm.Required(str)
 age = orm.Optional(int)
 phone = orm.Optional(str)
  27. Граф миграций D B A E C 0001_initial.py 0002_20161013 _0922.py

    0002_20161013 _1015.py 0003_20161013_1015.py 0004_20161013_1015.py
  28. Сравнение с Django, SQLAlchemy • В Django и SQLAlchemy файл

    миграции содержит перечень операций изменения таблиц • В Пони файл миграций содержит не список операций изменения, а полный набор сущностей
  29. Сравнение с Django, SQLAlchemy • Когда Alembic создает новую автоматически

    сгенерированную миграцию, сравнивается содержимое БД с текущими моделями проекта • Когда Pony создает новую миграцию, сравниваются сущности последней миграции и текущие сущности проекта, содержимое БД не анализируется • Django как и Пони не анализирует БД, но прежнее состояние моделей восстанавливается из всей цепочки миграций
  30. Теперь Pony ORM распространяется под лицензией Apache 2.0! То есть

    Pony полностью бесплатна для любого проекта!
  31. Ближайшие перспективы Pony • PEP8 • Интеграция с фронтендом •

    to_json() для результата запроса • PonyJS • GraphQL • Online редактор как инструмент полного цикла разработки