⬆️ ⬇️

The introduction of high-performance Pony ORM in the project Django

The previous post on performance, described Pony ORM , which showed fantastic results compared to Django ORM and SQLAlchemy.



Impressed with such extraordinary results and concerned about the performance of my own project, I decided to implement Pony ORM in my project. What came out of it, see tackle.





The temptations



Of course, you could rewrite the project again. This temptation always hovers over the developer who has encountered problems whose roots lie in the tool used. However, the amount of code already written, a huge branched data model, and the impressive number of fully working plug-in applications for Django used in the project put a big and bold cross on this path.

')

Alternative



Some time ago, in search of an alternative to Django ORM, I came across an interesting project Aldjemy . This is a small link above Django ORM, which allows you to use the structure of Django models to build an alternative hierarchy of SQLAlchemy models. This approach makes it possible, while preserving the basis of the project (including the entire Django data model), to use SQLAlchemy precisely and only where you want. Inspired by the idea of ​​this project and having licked a number of lines of code , I made a similar library for Pony ORM to Django ORM, naming it djony (DJango pONY).



Short excursion



Using djony is more than simple. After installing djony into the system (for example, using the command pip install git+git://github.com/nnseva/djony.git@master#egg=djony ), we can specify djony as one of the used applications in settings.py. You just need to remember that djony must be the most recent application in the list.



Now, each of the Django models (namely, models as classes) has the `p` attribute (from the word pony). This is the model Pony ORM. It can be used wherever, according to the Pony documentation , you need to use a model. You will also need the orm module, you can import it from the pony module ( from pony import orm ). Alternatively, you can use the djony.orm module, which contains all the variables of the pony.orm module, as well as djony-specific functions and variables.



Objects of the Pony ORM models will contain only data fields and collections of objects according to the data model and the structure of relations (perhaps in the future it will be necessary to fasten the ability to add members to the automatically created Pony ORM models).



Test



Let us now try to test one of the most popular operations for performance — user rights checking.



For Django, we will use the out-of-the-box User.has_perm function. Of course, for Pony ORM you will need to write code approximately equivalent to this function:



 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 




Let's take a look at the test results (for testing, 1000 users were created in the database, performing the role of ballast for the test).



 >>> 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 




As you can see, we have received an increase of more than 4 times. Not bad!



Application. Test code.





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 

Source: https://habr.com/ru/post/197962/



All Articles