Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Внедрение высокопроизводительного Pony ORM в план Django

Anna | 16.06.2014 | нет комментариев
Предыдущий пост посвященный продуктивности, описывал Pony ORM, показавший фантастические итоги по сопоставлению с Django ORM и SQLAlchemy.

Впечатленный столь неординарными итогами и озадаченный эффективностью собственного плана, я решил внедрить Pony ORM в свой план. Что из этого получилось, см подкатом.

Соблазны

Безусловно, дозволено было бы переписать план снова. Данный соблазн неизменно витает над разработчиком, встретившим задачи, корни которых лежат в используемом инструменте. Впрочем, объем теснее написанного кода, большая разветвленная модель данных, да и впечатляющее число использованных в плане абсолютно рабочих плагинов-приложений для Django ставят на этом пути огромный и толстый крест.

Альтернатива

Некоторое время назад, в поисках альтернативы Django ORM, я наткнулся на увлекательный план Aldjemy. Это маленькая навеска над Django ORM, разрешающая применять конструкцию моделей Django для построения альтернативной иерархии моделей SQLAlchemy. Такой подход дает вероятность, сберегая основу плана (в том числе — всю модель данных Django), применять SQLAlchemy именно и только там, где вы захотите. Вдохновленный идеей этого плана и слизав некоторое число строк кода, я сделал аналогичную библиотекудля прикрутки Pony ORM к Django ORM, назвав ее djony (DJango pONY).

Короткий экскурс

Применение djony больше чем легко. Позже установки djony в систему (скажем с поддержкой команды pip install git git://github.com/nnseva/djony.git@master#egg=djony), мы можем указать djony в качестве одного из используемых приложений в settings.py. Необходимо только помнить, что djony непременно должен быть самым последним приложением в списке.

Сейчас у всякой из моделей Django (именно моделей — как классов) возник признак `p` (от слова pony). Это и есть модель Pony ORM. Ее дозволено применять всюду, где согласно документации Pony, необходимо применять модель. Вам потребуется также модуль orm, его дозволено импортировать из модуля pony (from pony import orm). Альтернативно, вы можете применять модуль djony.orm, содержащий все переменные модуля pony.orm, а также специфические для djony функции и переменные.

Объекты моделей Pony ORM будут содержать только поля данных и коллекции объектов согласно модели данных и структуре отношений (допустимо, в грядущем нужно будет прикрутить вероятность добавления своих членов в механически создаваемые модели Pony ORM).

Тест

Испробуем сейчас потестировать на продуктивность одну из самых знаменитых операций — проверку прав пользователя.

Для Django мы будем применять готовую функцию User.has_perm. Разумеется, для Pony ORM необходимо будет написать код, приблизительно равнозначный этой функции::

def has_perm(user,perm):
    if not user.is_active:
        return False
    app_label,codename = perm.split('.')
    for p in orm.select(
            p for p in Permission.p
            if
                (user in p.user_set or user in p.group_set.user_set) and
                p.codename == codename and
                p.content_type.app_label == app_label
    ):
        return True
    return False

Посмотрим на итоги тестирования (для тестирования, в базе было заведено 1000 пользователей, исполняющих для теста роль балласта).

>>> import test_pony
>>> import test_django
>>> test_django.test_django()
check user permissions: django req/seq: 170.308759221 req time (ms): 5.8716886
>>> test_pony.test_pony()
check user permissions: pony req/seq: 729.517146462 req time (ms): 1.3707697

Как видим, мы получили приход больше чем в 4 раза. Дюже хорошо!

Приложение. Код тестов.

test_django.py
import datetime

from django.contrib.auth.models import User

def test_django():
    t1 = datetime.datetime.now()
    for i in range(10000):
        test()
    t2 = datetime.datetime.now()
    print "check user permissions: django req/seq:",10000/(t2-t1).total_seconds(),'req time (ms):',(t2-t1).total_seconds()/10.

def test():
    user = User.objects.get(username='testuser')
    return user.has_perm('auth.add_user')
test_pony.py
import datetime

from django.contrib.auth.models import User, Permission

def test_pony():
    t1 = datetime.datetime.now()
    for i in range(10000):
        test()
    t2 = datetime.datetime.now()
    print "check user permissions: pony req/seq:",10000/(t2-t1).total_seconds(),'req time (ms):',(t2-t1).total_seconds()/10.

from djony import orm

@orm.db_session
def test():
    user = User.p.get(username='testuser')
    return has_perm(user,'auth.add_user')

def has_perm(user,perm):
    if not user.is_active:
        return False
    app_label,codename = perm.split('.')
    for p in orm.select(
            p for p in Permission.p
            if
                (user in p.user_set or user in p.group_set.user_set) and
                p.codename == codename and
                p.content_type.app_label == app_label
    ):
        return True
    return False
Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB