People build composable and reusable abstractions on top of sql all the time.
In the same vein that different languages provide higher-level abstractions for machine code or JVM bytecode.
There are so many different ways to abstract aspects for different goals.
Yes: https://docs.djangoproject.com/en/4.1/topics/db/queries/#ret... and https://docs.djangoproject.com/en/4.1/topics/db/queries/#loo...
> Can I compose named functions that represent transforms (map, filter, etc.) in a type-safe fashion with each other and have those translate to appropriate CTEs
The Django ORM doesn't use CTEs (yet). It's common however to create and compose custom filter operations which the ORM will then combine into larger SQL queries. A rough example:
def today(qs):
return qs.filter(created__date = datetime.date.today())
def tagged(qs, tag):
# This becomes a many-to-many lookup
return qs.filter(tags__tag = tag)
entries = today(tagged(Entry.objects.all(), "python")
This would build the following SQL query: SELECT
"blog_entry"."id",
"blog_entry"."created",
"blog_entry"."slug",
"blog_entry"."metadata",
"blog_entry"."search_document",
"blog_entry"."import_ref",
"blog_entry"."card_image",
"blog_entry"."series_id",
"blog_entry"."title",
"blog_entry"."body",
"blog_entry"."tweet_html",
"blog_entry"."extra_head_html",
"blog_entry"."custom_template"
FROM
"blog_entry"
INNER JOIN "blog_entry_tags" ON ("blog_entry"."id" = "blog_entry_tags"."entry_id")
INNER JOIN "blog_tag" ON ("blog_entry_tags"."tag_id" = "blog_tag"."id")
WHERE
(
"blog_tag"."tag" = 'python'
AND ("blog_entry"."created" AT TIME ZONE 'UTC') :: date = '2022-07-30'
)
ORDER BY
"blog_entry"."created" DESC
There are plenty of more sophisticated ways to build abstractions over queries in Django - using custom QuerySet methods for example: https://docs.djangoproject.com/en/4.1/topics/db/managers/#ca...https://www.edgedb.com/ https://www.edgedb.com/showcase/edgeql