diff options
| author | François Freitag <mail@franek.fr> | 2017-06-01 16:56:51 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-06-01 17:50:41 -0400 |
| commit | edee5a8de6afb34a9247de2bb73ab66397a6e573 (patch) | |
| tree | e306f62cdbfc1e28ffb119bdbd7870a138e91dd9 /django | |
| parent | bf50ae821021c4f7cd608d2bd1f2dfff98f3ceb9 (diff) | |
Fixed #27639 -- Added chunk_size parameter to QuerySet.iterator().
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/models/query.py | 13 | ||||
| -rw-r--r-- | django/db/models/sql/compiler.py | 10 |
2 files changed, 13 insertions, 10 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py index fdf720cb8a..bc9ee1c5f8 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -20,7 +20,7 @@ from django.db.models.expressions import F from django.db.models.fields import AutoField from django.db.models.functions import Trunc from django.db.models.query_utils import InvalidQuery, Q -from django.db.models.sql.constants import CURSOR +from django.db.models.sql.constants import CURSOR, GET_ITERATOR_CHUNK_SIZE from django.utils import timezone from django.utils.functional import cached_property, partition from django.utils.version import get_version @@ -33,9 +33,10 @@ EmptyResultSet = sql.EmptyResultSet class BaseIterable: - def __init__(self, queryset, chunked_fetch=False): + def __init__(self, queryset, chunked_fetch=False, chunk_size=GET_ITERATOR_CHUNK_SIZE): self.queryset = queryset self.chunked_fetch = chunked_fetch + self.chunk_size = chunk_size class ModelIterable(BaseIterable): @@ -47,7 +48,7 @@ class ModelIterable(BaseIterable): compiler = queryset.query.get_compiler(using=db) # Execute the query. This will also fill compiler.select, klass_info, # and annotations. - results = compiler.execute_sql(chunked_fetch=self.chunked_fetch) + results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size) select, klass_info, annotation_col_map = (compiler.select, compiler.klass_info, compiler.annotation_col_map) model_cls = klass_info['model'] @@ -301,13 +302,15 @@ class QuerySet: # METHODS THAT DO DATABASE QUERIES # #################################### - def iterator(self): + def iterator(self, chunk_size=2000): """ An iterator over the results from applying this QuerySet to the database. """ + if chunk_size <= 0: + raise ValueError('Chunk size must be strictly positive.') use_chunked_fetch = not connections[self.db].settings_dict.get('DISABLE_SERVER_SIDE_CURSORS') - return iter(self._iterable_class(self, chunked_fetch=use_chunked_fetch)) + return iter(self._iterable_class(self, chunked_fetch=use_chunked_fetch, chunk_size=chunk_size)) def aggregate(self, *args, **kwargs): """ diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 5c7b5b7f51..f81861ddba 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -883,7 +883,7 @@ class SQLCompiler: self.query.set_extra_mask(['a']) return bool(self.execute_sql(SINGLE)) - def execute_sql(self, result_type=MULTI, chunked_fetch=False): + def execute_sql(self, result_type=MULTI, chunked_fetch=False, chunk_size=GET_ITERATOR_CHUNK_SIZE): """ Run the query against the database and return the result(s). The return value is a single data item if result_type is SINGLE, or an @@ -937,7 +937,8 @@ class SQLCompiler: result = cursor_iter( cursor, self.connection.features.empty_fetchmany_value, - self.col_count + self.col_count, + chunk_size, ) if not chunked_fetch and not self.connection.features.can_use_chunked_reads: try: @@ -1298,14 +1299,13 @@ class SQLAggregateCompiler(SQLCompiler): return sql, params -def cursor_iter(cursor, sentinel, col_count): +def cursor_iter(cursor, sentinel, col_count, itersize): """ Yield blocks of rows from a cursor and ensure the cursor is closed when done. """ try: - for rows in iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)), - sentinel): + for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel): yield [r[0:col_count] for r in rows] finally: cursor.close() |
