Building subqueries inside Django gives the rest of Django access to them for things like aggregation or filters.
There is definitely a benefit to querying everything the same way if you can, so that way it's easy to grep where different tables are being accessed. Cuts down on bugs, security issues, etc.
Admittedly I rarely have to deal with the need for highly performant database code. But one could argue that performance problems are often better handled via caching or denormalisation (which really boil down to the same thing) than by clever work on the db side.
The way I define queries by using a custom language in the form of keyword arguments makes me wonder why I don't just learn SQL instead?
I would much rather do something like:
models.Foo.objects.filter(sql=my_sql_query_str)
Instead of something like: models.Foo.objects.filter(name='bar', parent__siblings__count__lt=3)
And no special abstraction on SQL in the form of special classes. Just a string of SQL that I compose with Python string formatting. SQL isn't scary. I don't see the need to try and hide it.you can already do this. the django ORM has a convenient and expressive API for a lot of very common types of queries, but lets you easily drop back into raw SQL when you have a high complexity query that you want to write by hand.
You can just add various filter conditions to a dictionary, and then unpack them into the filter as kwargs. That way you can still build up the dictionary using if/else blocks or however you would normally build up a SQL query string.
SQL isn't scary, but for simple queries the Django ORM usually a lot more legible if you take the time to learn the DSL.
sounds like an SQL injection waiting to happen
1: https://github.com/kennethreitz/records (same author as Requests)
You have to learn SQL to use the Django ORM anyways; it's required knowledge in order to be able to wield the higher level abstraction effectively. However, the way you write a lot of these things in SQL is substantially more verbose and harder to compose.
Could you give an example of something that's hard to compose with SQL? I'm sure ORMs have their advantages, I just want to understand how much benefit I could get from using one.
Book.objects.filter(author__address__country='GB')
Rather than having to manage the joins with the author and address tables yourself.For example, in SQL if I wanted to return records where an records could be found in both tables, I would use an inner join, whereas if I wanted to return all records from 'author' and any related information from 'address' (and return NULL if a suitable address entry couldn't be found) I could use a left join. Does the ORM you have in mind give you that flexibility?
It's probably worth mentioning that some SQL tools will suggest fields that can be joined on, if this is a concern.
Post.objects.prefetch_related('author__company')
Often I want to avoid joins on big tables but still need to prefetch related fields on the objects I'm fetching. Example above fetches all the authors for the returned post, and then fetches all their companies. That's two additional fetches I don't have to write. published_posts = Post.objects.filter(publish_date__gte=now())
post_count = published_posts.count()
You can't just append a COUNT to an SQL query, you'd have to write two queries, or one query that returned both. The above code produces two different queries, so it's much more composable.I use it for tacking on extra filtering terms as well:
if category:
published_posts = published_posts.filter(category=category)SELECT published_posts, COUNT(published_posts) FROM Table1 WHERE publish_date > '2017-02-20' GROUP BY published_posts
https://docs.djangoproject.com/en/1.10/ref/models/querysets/...
You write your query as a string template, and then jinjasql interpolates the variables and provides the bind parameters. Makes it easy to maintain complex queries.