[Django] #30874: Allow disabling of lazy loading of model and related fields on querysets

12 views
Skip to first unread message

Django

unread,
Oct 11, 2019, 12:04:51 PM10/11/19
to django-...@googlegroups.com
#30874: Allow disabling of lazy loading of model and related fields on querysets
-----------------------------------------+------------------------
Reporter: Rowan Seymour | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 2.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
Lazy field fetching can be super convenient but also a liability at scale.
For example:


{{{
for book in Book.objects.only("id").all():
book.author # lazily fetches author field
book.categories.all() # lazily fetches related field
}}}

You might be trying to optimize your query by using `only` but then later
you reference another field and don't realize there's now a new DB hit for
every object you've loaded.

What would be really useful in situations like this to disable lazy
fetching of fields and related fields, so if you haven't included them
with `only` or `select_related`, the field access raises an exception.

{{{
for book in Book.objects(allow_lazy=False).only("id").all():
book.author # raises exception
}}}

Indicating that you need to correct the query..

{{{
for book in Book.objects(allow_lazy=False).only(''id",
"author").select_related("categories").all():
book.author
book.categories.all()
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/30874>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 11, 2019, 6:26:52 PM10/11/19
to django-...@googlegroups.com
#30874: Allow disabling of lazy loading of model and related fields on querysets
-------------------------------+--------------------------------------

Reporter: Rowan Seymour | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 2.2
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------

Comment (by Simon Charette):

Shameless plug for [https://github.com/charettes/django-seal a third-party
library that implements just that].

The API is quite simple; it exposes a `seal()` method on `QuerySet` and
`Model` instances that turn all fetching attempts into warnings that can
be elevated to `UnsealedAttributeAccess(AttributeError)`. We've been using
it internally for a few projects so far and it does wonder to catch sneaky
queries and makes field deferring less of a foot gun.

Such an API will be necessary in a future `async` world where lazy
fetching cannot be awaited and thus must be prevented.

There's also a somewhat related approach to this problem in #28586 that
suggests to automatically prefetch ''to one'' fields.
[https://groups.google.com/forum/#!topic/django-developers/EplZGj-ejvg I
tend to agree with Anssi that this is a recipe for disaster]. In my
opinion it makes it impossible to determine what the ORM will do as your
project evolves and more relationships are added to your models, the same
kind of issues that calling `select_related()` without fields has.

Developer mailing list threads about both approaches

- https://groups.google.com/d/msg/django-
developers/AR6HwgSYV-M/bVmY9vs5EQAJ
- https://groups.google.com/d/msg/django-developers/EplZGj-
ejvg/nYb0jxSTBgAJ

--
Ticket URL: <https://code.djangoproject.com/ticket/30874#comment:1>

Django

unread,
Oct 14, 2019, 8:57:01 PM10/14/19
to django-...@googlegroups.com
#30874: Allow disabling of lazy loading of model and related fields on querysets
-------------------------------+--------------------------------------

Reporter: Rowan Seymour | Owner: nobody
Type: Uncategorized | Status: closed
Component: Uncategorized | Version: 2.2
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Simon Charette):

* status: new => closed
* resolution: => duplicate


Comment:

This is a duplicate of #22492.

--
Ticket URL: <https://code.djangoproject.com/ticket/30874#comment:2>

Reply all
Reply to author
Forward
0 new messages