mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #29984 -- Added QuerySet.iterator() support for prefetching related objects.
Co-authored-by: Raphael Kimmig <raphael.kimmig@ampad.de> Co-authored-by: Simon Charette <charette.s@gmail.com>
This commit is contained in:
committed by
Mariusz Felisiak
parent
c27932ec93
commit
edbf930287
@@ -81,6 +81,10 @@ details on these changes.
|
||||
|
||||
* ``django.contrib.sessions.serializers.PickleSerializer`` will be removed.
|
||||
|
||||
* The usage of ``QuerySet.iterator()`` on a queryset that prefetches related
|
||||
objects without providing the ``chunk_size`` argument will no longer be
|
||||
allowed.
|
||||
|
||||
.. _deprecation-removed-in-4.1:
|
||||
|
||||
4.1
|
||||
|
||||
@@ -1215,8 +1215,10 @@ could be generated, which, depending on the database, might have performance
|
||||
problems of its own when it comes to parsing or executing the SQL query. Always
|
||||
profile for your use case!
|
||||
|
||||
Note that if you use ``iterator()`` to run the query, ``prefetch_related()``
|
||||
calls will be ignored since these two optimizations do not make sense together.
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
If you use ``iterator()`` to run the query, ``prefetch_related()``
|
||||
calls will only be observed if a value for ``chunk_size`` is provided.
|
||||
|
||||
You can use the :class:`~django.db.models.Prefetch` object to further control
|
||||
the prefetch operation.
|
||||
@@ -2341,7 +2343,7 @@ If you pass ``in_bulk()`` an empty list, you'll get an empty dictionary.
|
||||
``iterator()``
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. method:: iterator(chunk_size=2000)
|
||||
.. method:: iterator(chunk_size=None)
|
||||
|
||||
Evaluates the ``QuerySet`` (by performing the query) and returns an iterator
|
||||
(see :pep:`234`) over the results. A ``QuerySet`` typically caches its results
|
||||
@@ -2355,12 +2357,34 @@ performance and a significant reduction in memory.
|
||||
Note that using ``iterator()`` on a ``QuerySet`` which has already been
|
||||
evaluated will force it to evaluate again, repeating the query.
|
||||
|
||||
Also, use of ``iterator()`` causes previous ``prefetch_related()`` calls to be
|
||||
ignored since these two optimizations do not make sense together.
|
||||
``iterator()`` is compatible with previous calls to ``prefetch_related()`` as
|
||||
long as ``chunk_size`` is given. Larger values will necessitate fewer queries
|
||||
to accomplish the prefetching at the cost of greater memory usage.
|
||||
|
||||
On some databases (e.g. Oracle, `SQLite
|
||||
<https://www.sqlite.org/limits.html#max_variable_number>`_), the maximum number
|
||||
of terms in an SQL ``IN`` clause might be limited. Hence values below this
|
||||
limit should be used. (In particular, when prefetching across two or more
|
||||
relations, a ``chunk_size`` should be small enough that the anticipated number
|
||||
of results for each prefetched relation still falls below the limit.)
|
||||
|
||||
So long as the QuerySet does not prefetch any related objects, providing no
|
||||
value for ``chunk_size`` will result in Django using an implicit default of
|
||||
2000.
|
||||
|
||||
Depending on the database backend, query results will either be loaded all at
|
||||
once or streamed from the database using server-side cursors.
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
|
||||
Support for prefetching related objects was added.
|
||||
|
||||
.. deprecated:: 4.1
|
||||
|
||||
Using ``iterator()`` on a queryset that prefetches related objects without
|
||||
providing the ``chunk_size`` is deprecated. In Django 5.0, an exception
|
||||
will be raise.
|
||||
|
||||
With server-side cursors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -2399,8 +2423,10 @@ The ``chunk_size`` parameter controls the size of batches Django retrieves from
|
||||
the database driver. Larger batches decrease the overhead of communicating with
|
||||
the database driver at the expense of a slight increase in memory consumption.
|
||||
|
||||
The default value of ``chunk_size``, 2000, comes from `a calculation on the
|
||||
psycopg mailing list <https://www.postgresql.org/message-id/4D2F2C71.8080805%40dndg.it>`_:
|
||||
So long as the QuerySet does not prefetch any related objects, providing no
|
||||
value for ``chunk_size`` will result in Django using an implicit default of
|
||||
2000, a value derived from `a calculation on the psycopg mailing list
|
||||
<https://www.postgresql.org/message-id/4D2F2C71.8080805%40dndg.it>`_:
|
||||
|
||||
Assuming rows of 10-20 columns with a mix of textual and numeric data, 2000
|
||||
is going to fetch less than 100KB of data, which seems a good compromise
|
||||
|
||||
@@ -239,6 +239,10 @@ Models
|
||||
insertion fails uniqueness constraints. This is supported on MariaDB, MySQL,
|
||||
PostgreSQL, and SQLite 3.24+.
|
||||
|
||||
* :meth:`.QuerySet.iterator` now supports prefetching related objects as long
|
||||
as the ``chunk_size`` argument is provided. In older versions, no prefetching
|
||||
was done.
|
||||
|
||||
Requests and Responses
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -430,6 +434,11 @@ Miscellaneous
|
||||
* ``django.contrib.sessions.serializers.PickleSerializer`` is deprecated due to
|
||||
the risk of remote code execution.
|
||||
|
||||
* The usage of ``QuerySet.iterator()`` on a queryset that prefetches related
|
||||
objects without providing the ``chunk_size`` argument is deprecated. In older
|
||||
versions, no prefetching was done. Providing a value for ``chunk_size``
|
||||
signifies that the additional query per chunk needed to prefetch is desired.
|
||||
|
||||
Features removed in 4.1
|
||||
=======================
|
||||
|
||||
|
||||
Reference in New Issue
Block a user