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

PythonQL: вся мощь современных языков запросов ...

PythonQL: вся мощь современных языков запросов прямо в Питоне

Павел Велихов (Finstar Labs, Head of Data Science) @ Moscow Python №42

"Проект PythonQL – это попытка унифицировать доступ к различным базам данных, расширив Питон мощным языком запросов. Спикер расскажет об этом расширении, самых интересных сценариях использования и обсудит дальнейшие планы развития".

Видео: http://www.moscowpython.ru/meetup/42/pythonql/

Avatar for Moscow Python Meetup

Moscow Python Meetup

January 19, 2017
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. О чем будет доклад ❖ Кто мы, что это, зачем

    нужно? ❖ Краткое введение в PythonQL ❖ Примеры сценариев, где особенно удобно пользоваться PythonQL ❖ Текущая реализация, планы на будущее
  2. Во-первых: команда ❖ Daniela Florescu ❖ XQuery, JSONiq, Oracle, Zorba

    ❖ Pavel Velikhov ❖ XQuery (Enosys,Sedna), SciDB, Data Science ❖ Sergey Vinogradov ❖ Data Science * все работы ведутся в свободное от основной работы время ** поэтому проект движется так неспешно
  3. Мотивация 2: Одна вьюшка для всех СУБД ❖ Научились писать

    запросы к одной СУБД? ❖ Ничего не мешает писать запросы сразу к нескольким базам, причем разным (например сджоинить PostgreSQL, Mongo и CSV файл) ❖ Еще красивее: ❖ Один раз пишем сложный запрос, который ходит по разным СУБД, все там правильно матчит, чистит, интегрирует. ❖ Потом сверху пишем простенькие SELECT - запросы
  4. Мотивация 3: Для данных есть языки запросов, а для структур

    внутри Питона - нет? Несправедливость! ❖ Языки запросов вроде SQL очень удобны для всякой ad-hoc аналитики. ❖ В Питоне для подобных целей приходится писать мини- скрипты, что намного медленней и выглядит так себе ❖ Даешь всю мощь SQL (даже чуть поболее) внутри Питона для любых целей!
  5. Наши тезисы ❖ Освоить голый язык запросов (без библиотек и

    т.п.) хорошим программистам не представляет труда ❖ Работать с большим количеством разных СУБД - вот эту уже неудобно по ряду причин. Именно из-за этого программисты не любят изучать новые СУБД. ❖ Перетаскиваем язык запросов из СУБД в Питон. Получаем унифицированный язык запросов. Даем возможность одним запросом обращаться в несколько баз сразу и к своим структурам данных ❖ Если все это приемлемо работает*, получаем огромный бонус к производительности, декларативности и счастью
  6. PythonQL: Дизайн языка ❖ PythonQL состоит из нескольких компонент: ❖

    Основной язык: расширение comprehensions (list,set,map). ❖ Путевые выражения (сверху JSON структур) ❖ Try-except выражение ❖ Конструктор кортежей
  7. PythonQL: Основной язык ❖ Похож и на SQL и на

    JSONiq, но является строгим супер- множеством Питона ❖ Минимальное расширение Питона, особенно это касается ключевых слов. ❖ По максимуму используются конструкции Питона, например нет своих кванторов существования и всеобщности, нет case statement, агрегатные и статистические функции из стандартных библиотек ❖ Самое большое расширение - это pattern matching и запросы с window. Функционал window взят из XQuery.
  8. PythonQL: Основной язык query_expr := [ ‘select’ ] expr (

    for | let | pattern | window) ( for | let | pattern | window | where | group by | order by | count )* Пример: [ select (name, sales) for p in product_db, o in sales_db where p.product_id = o.product_id group by p.product_name as name let sales = sum( [ try int(x.amount) except 0 for x in o ] ) order by sales desc ]
  9. PythonQL: Маленькие добавки ❖ Путевые выражения очень хорошо себя показали

    в XQuery и JSONiq. ❖ for x in object ./ ‘car’ ./ ‘make’ ❖ for x in object .// _ ./ ‘make’ ❖ Try-except: ❖ В Питоне механизм исключений реализован в statement, а не в expression ❖ Добавили выражение: try expr except expr ❖ Конструктор кортежей select (x.fname as fname, y.lname as lname) for x in names
  10. Pattern Matching ❖ Работа со всякими слабо-структурированными JSONами (собираемся также

    сделать поддержку XML): match { "last_name" : as l, "age" : as a where a > 25, "address" : { "city" : "San Jose", "zipcode" : as z } } as p in people
  11. Window x = [1,2,3,4,5,6,7] res = [ select (y,sum(w) as

    sum) for sliding window w in x start y at s when True end at e when e-s == 2 ]
  12. Несколько сценариев использования (DataScience) ❖ Customer Journey: гетерогенные временные ряды

    событий о всех действиях клиента ❖ Data Cleaning & Integration: традиционный сценарий, но до сих пор тяжелый ❖ Model Evaluation: интересный сценарий, метод, который предлагаем мы сейчас почти не используется
  13. Customer Journey ❖ Путешесвие клиента через все стадии услуги ❖

    Разнородные события: ❖ открыл счет, перевод денег, заявка на кредит, выдача кредита, выплата кредита, звонок из кол- центра, закрытие счета ❖ Нужна разнородная ad-hoc аналитика, быстрая проверка гипотез
  14. Customer Journey Сколько клиентов с балансом > 300 долларов в

    разных штатах? res = [ # Пробежимся во всем клиентам (клиент - это список событий) select (state, len(balance) as n_customers) for cj in cust_journeys # Выделим данные о клиенте из события об открытие счета let c_data = [select e for e in cj where e.event_name==‘open’][0].client_data, # Достанем суммы транзакцию по внесению и снятию денег со счета withdrawals = [select e.amount for e in cj where e.event_name=='withdraw'], deposits = [select e.amount for e in cj where e.event_name=='deposit'] # Посчитаем баланс и отфильтруем клиентов let balance = sum(deposits) - sum(withdrawals) where balance > 300 # Сгруппируем по штату group by c_data.address.state as state ]
  15. Customer Journey Клиенты, которым было отказано в кредите, и которые

    закрыли счета в течение месяца после этого события. n_closed_and_refused = [ # Пробежимся по всем клиентам (клиент = список событий) select cj for cj in cust_journeys # Найдем событие закрытия счета, если такого нет, пропустим этого клиента let close = next((select e for e in cj where e.event_name=='close'),None) where close # Узнаем дату последней заявки на кредит, если заявки не было, пропустим клиента let req = try [select e for e in cj where e.event_name==‘loan_req’][-1] except None where req let last_request_date = parse(req.date), close_date = parse(close.date) # Если кредит не выдали и заявка была за месяц или раньше - это наш клиент where (close_date - last_request_date).days < 30 and not [select e for e in cj where e.event_name=='loan_issued' and (parse(e.date) - last_request_date) > 0 ] ]
  16. Текущая реализация ❖ Ставится стандартным pip install ❖ Файлы PythonQL

    помечаются специальной кодировкой ❖ #coding: pythonql ❖ Простой процессор запросов, написанный на Питоне. Все внутренние выражения компилируются и исполняются через eval. ❖ Нет оптимизатора и планировщика запросов ❖ Интеграция с СУБД, Apache Spark, pandas на уровне структур данных в оперативной памяти
  17. Дальнейший план: ❖ Поддержка Jupyter нотбуков, интерактивного PythonQL ❖ Простой

    wrapper для SQL баз, Apache Spark ❖ Мощный собственный процессор на C++ или Cython ❖ Планировщик запросов и оптимизатор
  18. Спасибо за внимание ❖ Сайт проекта: www.pythonql.org, оттуда ссылки на

    GitHub и несколько полных сценариев ❖ Есть документация в стиле tutorial на GitHub, покрывает весь основной функционал языка ❖ Есть mailing list, ссылка со страницы GitHub ❖ pip install pythonql (Python 2.7) ❖ pip install pythonql3 (Python 3)