A simple and impossible query in django
The ORM with the forms, according to my opinion, are the best and most noteworthy parts that Django has. Thanks to both these components work with this framework is easier. But, that being said, obviously, they can have errors or are not complete. In this post, I am going to propose two lookups, to complete the ORM.
Two months ago I read in stackoverflow a question that asked: “How can you make a very simple SQL query with Django ORM?, as the following”:
SELECT * FROM auth_user WHERE username LIKE '10%8%0%'
At the beginning I thought he was asking for a simple query using the lookup contains, but it was not that way. In Django you cannot get that in any way. You can only get the same result, emulating the query with regular expressions:
User.objects.filter(username__regex=r'^10.*8.*0.*$')
I realized two new lookups were necessary: “like” and “ilke”. I did a patch, and since they accepted it, I did a django-like module, so the community could test it easily. This module, through monkey-patching, makes the same that the patch. So the above query would look like this:
User.objects.filter(username__like='10%8%0%')
Reasons for
The reasons why I think that the patch should be added to the Django core are the following:
Readability
The query with “like” is more simple and shorter that with “regex”.
Performance
I think that this point is not the most important; Because even if there were no improvement, I would add these lookups, because they increase the readibility.
I show a table with the impreovement that you get after running the benchmark_like command, this compares the time to run 10.000 equivalent queries done with “like” or with “regex”.
| postgres | mysql | sqllite | oracle | |
| like | 0:00:50.727005 | 0:00:14.025656 | 0:01:36.089407 | ?:??:??.?????? |
| regex | 0:01:38.410019 | 0:02:57.255685 | 0:09:39.527765 | ?:??:??.?????? |
| improvement | 254% | 600% | 503% | ???% |
Incomplete funcionality
The backends that Django support, by default, are postgres, mysql, sqlite and oracle. In all of them you can do a query with LIKE, so there should exist a lookup with which you can do it too.
Reasons against
This patch has not been accepted, they have given me these reasons, with which, except the first, I don’t agree
This is not generic
It is true that the name is not generic and this has much relation with the SQL syntax. But this is not a reason to reject it, this is only a reason to look for a better name. It could be: econtains, the e meaning escape.
Performance
Before I said that with LIKE the queries are more efficient than with REGEX, but they told me that this did not occur in postgres. But as you can see in the table before, there is not as big of a difference as in mysql or sqlilite, but there is a great improvement nonetheless.
Duplication of code
Another motive that they have given me, is that if you can do it with regex, why do it by another way. I am complety against the duplicity of code, I am, sometime very strict with this, as you can see in a ticket in Django that I did. But in this case, it is not a duplication of code, or duplication of funcionality, and as I said: if you think by this way, you should not use contains, startswith, endwith, etc and do the queries with regex, which is possible, but you lose in readabity and performance
Related Posts:
- How visually detect visually cyclic import between our django applicationsComo detectar visualmente importaciones cíclicas entre nuestras aplicaciones django
- How to integrate forms in the Django admin site? django-form-admin¿Cómo integrar formularios en la administración de Django? django-form-admin
- Inline Editing and translating in DjangoEditando y traduciendo inline en Django
Leave a Reply Cancel reply
Categories
- comunication (2)
- contribuciones (9)
- django (5)
- Events (11)
- python (5)
- tamgrambpm (1)
- uniquid (72)
- confia (33)
- documentation (4)
- events-uniquid (28)
- janus (14)
- simplesamlphp (7)
- software (7)
- Virtualization (2)
- Escritorio (1)
- Yaco (9)
- Equipo (4)
- ytourism (2)
Archives
- November 2012 (1)
- July 2012 (2)
- June 2012 (2)
- May 2012 (2)
- April 2012 (1)
- March 2012 (2)
- February 2012 (5)
- January 2012 (3)
- December 2011 (5)
- November 2011 (8)
- October 2011 (7)
- September 2011 (3)
- August 2011 (3)
- July 2011 (1)
- June 2011 (3)
- May 2011 (5)
- March 2011 (2)
- February 2011 (1)
- December 2010 (1)
- November 2010 (2)
- October 2010 (2)
- September 2010 (1)
- June 2010 (3)
- May 2010 (1)
- April 2010 (1)
- March 2010 (3)
- February 2010 (3)
- January 2010 (3)
- December 2009 (6)
- November 2009 (7)
- June 2009 (1)
- May 2009 (1)
- March 2009 (1)
- December 2008 (1)
- June 2008 (1)
- April 2008 (1)
Recent Posts










Would this not work?
User.objects.extra(where=["username like='10%%8%%0%%'"])
(You have to escape the % but otherwise it is pretty much the SQL you want executed. )
This would be without the “=” symbol. But this was only a example. Imagine something like this:
User.objects.filter(Q(groups__name__ilike='john %') | Q(username__ilike='john%'))Maybe it is possible to do with extra/where. Even you can to do it without ORM. But I don’t think that was more readable
Thanks
I’ll immediately take hold of your rss as I can not find your e-mail subscription hyperlink or newsletter service. Do you have any? Kindly allow me recognise in order that I may just subscribe. Thanks.
English:
Global RSS: http://www.yaco.es/blog/en/feed/
Django RSS: http://www.yaco.es/blog/en/tag/django-en/feed/
Spanish:
Global RSS: http://www.yaco.es/blog/feed/
Django RSS: http://www.yaco.es/blog/tag/django/feed/
Wow, marvelous weblog format! How lengthy have you ever been running a blog for? you made blogging glance easy. The full look of your site is great, let alone the content material!
Great beat ! I wish to apprentice whilst you amend your web site, how can i subscribe for a blog website? The account aided me a acceptable deal. I were a little bit acquainted of this your broadcast offered brilliant clear concept