summaryrefslogtreecommitdiff
path: root/django/db/models/sql
diff options
context:
space:
mode:
authorFrançois Freitag <mail@franek.fr>2016-06-03 15:31:21 -0700
committerTim Graham <timograham@gmail.com>2017-01-11 09:25:37 -0500
commitf3b7c059367a4e82bbfc7e4f0d42b10975e79f0c (patch)
treed64dedfcd04cfbe8d7599aa6411597cccba6eb17 /django/db/models/sql
parent53bffe8d03f01bd3214a5404998cb965fb28cd0b (diff)
Refs #16614 -- Made QuerySet.iterator() use server-side cursors on PostgreSQL.
Thanks to Josh Smeaton for the idea of implementing server-side cursors in PostgreSQL from the iterator method, and Anssi Kääriäinen and Kevin Turner for their previous work. Also Simon Charette and Tim Graham for review.
Diffstat (limited to 'django/db/models/sql')
-rw-r--r--django/db/models/sql/compiler.py16
1 files changed, 10 insertions, 6 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index c37264ed0b..0778d38f4a 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -799,7 +799,7 @@ class SQLCompiler(object):
self.query.set_extra_mask(['a'])
return bool(self.execute_sql(SINGLE))
- def execute_sql(self, result_type=MULTI):
+ def execute_sql(self, result_type=MULTI, chunked_fetch=False):
"""
Run the query against the database and returns the result(s). The
return value is a single data item if result_type is SINGLE, or an
@@ -823,12 +823,16 @@ class SQLCompiler(object):
return iter([])
else:
return
-
- cursor = self.connection.cursor()
+ if chunked_fetch:
+ cursor = self.connection.chunked_cursor()
+ else:
+ cursor = self.connection.cursor()
try:
cursor.execute(sql, params)
except Exception:
- cursor.close()
+ with self.connection.wrap_database_errors:
+ # Closing a server-side cursor could yield an error
+ cursor.close()
raise
if result_type == CURSOR:
@@ -852,11 +856,11 @@ class SQLCompiler(object):
cursor, self.connection.features.empty_fetchmany_value,
self.col_count
)
- if not self.connection.features.can_use_chunked_reads:
+ if not chunked_fetch and not self.connection.features.can_use_chunked_reads:
try:
# If we are using non-chunked reads, we return the same data
# structure as normally, but ensure it is all read into memory
- # before going any further.
+ # before going any further. Use chunked_fetch if requested.
return list(result)
finally:
# done with the cursor