I don't fully understand the sync_to_async() operation here. So the underlying database is not async, then is Django just tossing the sync DB call onto a thread or something?
Re:Django 4.1
by megaman821 on Wednesday August 03, 2022 @09:55AM
(#32331697)
Yes, it is just being put on a thread. A future Django release will use async database drivers. Django is very incrementally adding support for async. I don't believe they have started work on async templates yet, which will be one of the last major areas before the framework is fully async.
Re:Django 4.1
by collinmanderson on Wednesday August 03, 2022 @10:15AM
(#32331968)
Yes, they're working from the top of the stack down, so first it was views+middleware, now it's the top layer of the database stack, and in future releases they'll work on pushing native async lower and lower in the stack.
Basically every function call that does db-queries needs an "a"-prefixed version. aget(), acreate(), aget_or_create(), acount(), aexists(), aiterator(), __aiter__, etc. And in future versions they'll work on the lower level, undocumented api, like _afetch_all(), aprefetch_related_objects(), compiler.aexecute_sql(), etc.
Eventually you'll probably need to switch database drivers to something that actually supports async.
Re:Django 4.1
by hansonkd13 on Wednesday August 03, 2022 @10:34AM
(#32332279)
Why do they need Async templates? When a template renders it should be pure data and fully on the CPU. It seems Async templates would encourage a bad behavior of doing n+1 queries inside the HTML.
Django makes a lot of use of lazy evaluation. You'll often construct a QuerySet object in a Django view like this:
entries = Entry.objects.filter(
category="python"
).order_by("-created")[:10]
Then pass that to a template which does this: {% for entry in entries %}...
Django doesn't actually execute the SQL query until the template starts looping through it.Async template rendering becomes necessary if you want the templates to be able to execute async SQL queries in this way.
Jinja has this feature already with the enable_async=True setting - I wrote a tiny bit about that in https://til.simonwillison.net/sqlite/related-content
Re:Django 4.1
by megaman821 on Wednesday August 03, 2022 @10:38AM
(#32332355)
My immediate thought would be custom template tags. Like `{% popular_articles %}` would have to connect to the DB and load the articles. I am sure there are other reasons too.
exactly, it fires database call in a separare thread with coroutine awaiting this threads result.
Is the limitation on django ORM? Because I can run asyncpg/psycopg3 and sqlalchemy with async mode without any issues.
https://docs.djangoproject.com/en/4.1/releases/4.1/#asynchro... :
`QuerySet` now provides an asynchronous interface for all data access operations. These are named as-per the existing synchronous operations but with an `a` prefix, for example `acreate()`, `aget()`, and so on.
> The new interface allows you to write asynchronous code without needing to wrap ORM operations in `sync_to_async()`:
> Note that, at this stage, the underlying database operations remain synchronous, with contributions ongoing to push asynchronous support down into the SQL compiler, and integrate asynchronous database drivers. The new asynchronous queryset interface currently encapsulates the necessary sync_to_async() operations for you, and will allow your code to take advantage of developments in the ORM’s asynchronous support as it evolves. […] See Asynchronous queries for details and limitations.## Asynchronous handlers for class-based views
> View subclasses may now define async HTTP method handlers: