Fixed #28459 -- Improved performance of ValuesListIterable.

This commit is contained in:
Sergey Fedoseev 2017-08-01 10:24:51 +05:00 committed by Tim Graham
parent 32d1bf2bdb
commit 2d136ede8a
1 changed files with 9 additions and 12 deletions

View File

@ -3,6 +3,7 @@ The main QuerySet implementation. This provides the public API for the ORM.
""" """
import copy import copy
import operator
import sys import sys
import warnings import warnings
from collections import OrderedDict, deque from collections import OrderedDict, deque
@ -116,10 +117,8 @@ class ValuesListIterable(BaseIterable):
query = queryset.query query = queryset.query
compiler = query.get_compiler(queryset.db) compiler = query.get_compiler(queryset.db)
if not query.extra_select and not query.annotation_select: results = compiler.results_iter()
for row in compiler.results_iter(): if queryset._fields:
yield tuple(row)
else:
field_names = list(query.values_select) field_names = list(query.values_select)
extra_names = list(query.extra_select) extra_names = list(query.extra_select)
annotation_names = list(query.annotation_select) annotation_names = list(query.annotation_select)
@ -127,15 +126,13 @@ class ValuesListIterable(BaseIterable):
# extra(select=...) cols are always at the start of the row. # extra(select=...) cols are always at the start of the row.
names = extra_names + field_names + annotation_names names = extra_names + field_names + annotation_names
if queryset._fields: fields = list(queryset._fields) + [f for f in annotation_names if f not in queryset._fields]
if fields != names:
# Reorder according to fields. # Reorder according to fields.
fields = list(queryset._fields) + [f for f in annotation_names if f not in queryset._fields] index_map = {name: idx for idx, name in enumerate(names)}
else: rowfactory = operator.itemgetter(*[index_map[f] for f in fields])
fields = names results = map(rowfactory, results)
return results
for row in compiler.results_iter():
data = dict(zip(names, row))
yield tuple(data[f] for f in fields)
class FlatValuesListIterable(BaseIterable): class FlatValuesListIterable(BaseIterable):