mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
Refs #33646 -- Added RawModelIterable.
This commit is contained in:
parent
aca9bb2a12
commit
77926176b2
@ -140,6 +140,50 @@ class ModelIterable(BaseIterable):
|
|||||||
yield obj
|
yield obj
|
||||||
|
|
||||||
|
|
||||||
|
class RawModelIterable(BaseIterable):
|
||||||
|
"""
|
||||||
|
Iterable that yields a model instance for each row from a raw queryset.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
# Cache some things for performance reasons outside the loop.
|
||||||
|
db = self.queryset.db
|
||||||
|
query = self.queryset.query
|
||||||
|
connection = connections[db]
|
||||||
|
compiler = connection.ops.compiler("SQLCompiler")(query, connection, db)
|
||||||
|
query_iterator = iter(query)
|
||||||
|
|
||||||
|
try:
|
||||||
|
(
|
||||||
|
model_init_names,
|
||||||
|
model_init_pos,
|
||||||
|
annotation_fields,
|
||||||
|
) = self.queryset.resolve_model_init_order()
|
||||||
|
model_cls = self.queryset.model
|
||||||
|
if model_cls._meta.pk.attname not in model_init_names:
|
||||||
|
raise exceptions.FieldDoesNotExist(
|
||||||
|
"Raw query must include the primary key"
|
||||||
|
)
|
||||||
|
fields = [self.queryset.model_fields.get(c) for c in self.queryset.columns]
|
||||||
|
converters = compiler.get_converters(
|
||||||
|
[f.get_col(f.model._meta.db_table) if f else None for f in fields]
|
||||||
|
)
|
||||||
|
if converters:
|
||||||
|
query_iterator = compiler.apply_converters(query_iterator, converters)
|
||||||
|
for values in query_iterator:
|
||||||
|
# Associate fields to values
|
||||||
|
model_init_values = [values[pos] for pos in model_init_pos]
|
||||||
|
instance = model_cls.from_db(db, model_init_names, model_init_values)
|
||||||
|
if annotation_fields:
|
||||||
|
for column, pos in annotation_fields:
|
||||||
|
setattr(instance, column, values[pos])
|
||||||
|
yield instance
|
||||||
|
finally:
|
||||||
|
# Done iterating the Query. If it has its own cursor, close it.
|
||||||
|
if hasattr(query, "cursor") and query.cursor:
|
||||||
|
query.cursor.close()
|
||||||
|
|
||||||
|
|
||||||
class ValuesIterable(BaseIterable):
|
class ValuesIterable(BaseIterable):
|
||||||
"""
|
"""
|
||||||
Iterable returned by QuerySet.values() that yields a dict for each row.
|
Iterable returned by QuerySet.values() that yields a dict for each row.
|
||||||
@ -1994,41 +2038,7 @@ class RawQuerySet:
|
|||||||
return iter(self._result_cache)
|
return iter(self._result_cache)
|
||||||
|
|
||||||
def iterator(self):
|
def iterator(self):
|
||||||
# Cache some things for performance reasons outside the loop.
|
yield from RawModelIterable(self)
|
||||||
db = self.db
|
|
||||||
connection = connections[db]
|
|
||||||
compiler = connection.ops.compiler("SQLCompiler")(self.query, connection, db)
|
|
||||||
query = iter(self.query)
|
|
||||||
|
|
||||||
try:
|
|
||||||
(
|
|
||||||
model_init_names,
|
|
||||||
model_init_pos,
|
|
||||||
annotation_fields,
|
|
||||||
) = self.resolve_model_init_order()
|
|
||||||
if self.model._meta.pk.attname not in model_init_names:
|
|
||||||
raise exceptions.FieldDoesNotExist(
|
|
||||||
"Raw query must include the primary key"
|
|
||||||
)
|
|
||||||
model_cls = self.model
|
|
||||||
fields = [self.model_fields.get(c) for c in self.columns]
|
|
||||||
converters = compiler.get_converters(
|
|
||||||
[f.get_col(f.model._meta.db_table) if f else None for f in fields]
|
|
||||||
)
|
|
||||||
if converters:
|
|
||||||
query = compiler.apply_converters(query, converters)
|
|
||||||
for values in query:
|
|
||||||
# Associate fields to values
|
|
||||||
model_init_values = [values[pos] for pos in model_init_pos]
|
|
||||||
instance = model_cls.from_db(db, model_init_names, model_init_values)
|
|
||||||
if annotation_fields:
|
|
||||||
for column, pos in annotation_fields:
|
|
||||||
setattr(instance, column, values[pos])
|
|
||||||
yield instance
|
|
||||||
finally:
|
|
||||||
# Done iterating the Query. If it has its own cursor, close it.
|
|
||||||
if hasattr(self.query, "cursor") and self.query.cursor:
|
|
||||||
self.query.cursor.close()
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s: %s>" % (self.__class__.__name__, self.query)
|
return "<%s: %s>" % (self.__class__.__name__, self.query)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user