вторник, 24 марта 2015 г.

CherryPy autoreloader

CherryPy классный легкий и удобный фреймворк под Python.
Столкнулся сегодня с такой проблемой: он автоматически перезапускается когда в исходниках происходят изменения (autoreloader). Вроде бы всё отлично, но возникает проблема с дебагом. Когда проект запущен из PyCharm авторелоад отсоединяет процесс от среды разработки и он болтается в памяти. Работает, продолжает обрабатывать запросы и релоадится при изменении фйлов. Но! Подключить дебагер нельзя. Попытка запуска завершается ошибкой с руганью на то, что порт занят и это вполне логично. Приходится искать этот процесс в таск-менеджере и убивать, либо добавлять функционал выключения CerryPy приложению и глушить его через браузер. И так каждый раз. Дико неудобно.
Ответ вроде бы лежит наповерхности, но есть нюанс.
Так вот, доки говорят, что autoreloader отключается через конфигуратор, нужно выставить engine.autoreload.on в False. Я попытался проделать это и пытался выставить это значение в секции [global] файла с конфигом. Долго мучился, но эффекта не добился.

Всё заработало и autoreloader отключился только после того как я добавил строку  cherrypy.config.update({'engine.autoreload.on':False}) перед запуском cherrypy.engine.start()


воскресенье, 22 марта 2015 г.

Python генераторы.

Продолжаю вникать в тонкости Python-а. Разглядывал как-то свой код и понял, что он не очень... в смысле совсем "не очень". А штука в том, что он хоть и написан на Python-е, но не полноценно питоновский. Что это значит? Да всё очень просто. По многолетней привычке я пишу:
result = list()
for itm in items:
    i = dict()
    i['Name'] = itm.name
    i['ItemID'] = itm.item_id
    result.append(i)
return result

Вот, код работает, но... я задумался, вспомнил что читал о Python-е, вспомнил про такую штуку как генераторы. Сказал себе: "Хмммм..." и, покопавшись в доках, написал:

return [{'Name': i.name, 'ItemID': i.item_id} for i in items]

Разница, как говорится, налицо. Код гораздо компактнее, понятнее и доки утверждают, что генераторы в Python работают быстрее циклов.

Генерировать можно не только списки. Словари тоже можно и это тоже очень просто:

result = { i.name: i.item_id for i in items}

Тут генератор возвращает словарь у которого name - это ключ, а item_id - значение. Примеры очень простые, но генераторы в Python очень мощная и гибкая штука и могут создавать довольно сложные объекты.

суббота, 21 марта 2015 г.

Вникаю в Python, генерирую классы для SQLAlchemy

Собственно изучаю Python как платформу для веб-разработки. Пока всё очень нравится. В качестве ORM фреймворка стал изучать SQLAlchemy, т.к. сегодня это стандарт де-факто для Python.

Встал вопрос как для SQLAlchemy сгенерить классы на основе существующей БД, писать всё руками совсем неохота. Поиски привели меня к sqlacodegen. Инсталится он просто: pip install sqlacodegen. Запускается из консольки: sqlacodegen mysql+mysqlconnector://user:password@localhost/dbname

То есть ему нужен коннектор. А вот с установкой коннектора под винду у меня возникли сложности. Ни один из популярных коннекторов из pip ставиться не захотел. Всем им понадобился C компилятор, а ставить студию или mingw мне не захотелось. Простое решение нашлось на сайте MySQL в виде готового инсталлятора под виндовс: http://dev.mysql.com/downloads/connector/python/

Эта связка отлично заработала и сгенерила мне нужные SQLAlchemy классы со всеми связями. sqlacodegen генерит код и выводит его в stdout. Поэтому нужно просто перенаправить вывод в нужный файл: sqlacodegen mysql+mysqlconnector://user:pass@localhost/dbname > model.py