Commits

mtre...@bcc190cf-cafb-0310-a4f2-bffc1f526a37  committed 4698192

Fixed #7411 -- worked around some possible transaction conflicts in SQLite.

  • Participants
  • Parent commits 538e5ad

Comments (0)

Files changed (4)

File django/db/backends/__init__.py

     time_field_needs_date = False
     interprets_empty_strings_as_nulls = False
     date_field_supports_time_value = True
+    can_use_chunked_reads = True
 
 class BaseDatabaseOperations(object):
     """

File django/db/backends/sqlite3/base.py

 
 class DatabaseFeatures(BaseDatabaseFeatures):
     supports_constraints = False
+    # SQLite cannot handle us only partially reading from a cursor's result set
+    # and then writing the same rows to the database in another cursor. This
+    # setting ensures we always read result sets fully into memory all in one
+    # go.
+    can_use_chunked_reads = False
 
 class DatabaseOperations(BaseDatabaseOperations):
     def date_extract_sql(self, lookup_type, field_name):

File django/db/models/sql/query.py

 
         # The MULTI case.
         if self.ordering_aliases:
-            return order_modified_iter(cursor, len(self.ordering_aliases),
+            result = order_modified_iter(cursor, len(self.ordering_aliases),
                     self.connection.features.empty_fetchmany_value)
-        return iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
+        result = iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
                 self.connection.features.empty_fetchmany_value)
+        if not self.connection.features.can_use_chunked_reads:
+            # 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.
+            return list(result)
+        return result
 
 # Use the backend's custom Query class if it defines one. Otherwise, use the
 # default.

File tests/regressiontests/queries/models.py

 import pickle
 
 from django.db import models
-from django.db.models.query import Q
+from django.db.models.query import Q, ITER_CHUNK_SIZE
 
 # Python 2.3 doesn't have sorted()
 try:
     sorted
 except NameError:
     from django.utils.itercompat import sorted
-                
+
 class Tag(models.Model):
     name = models.CharField(max_length=10)
     parent = models.ForeignKey('self', blank=True, null=True,
 >>> Item.objects.all()[0:0]
 []
 
+Bug #7411 - saving to db must work even with partially read result set in
+another cursor.
+
+>>> for num in range(2 * ITER_CHUNK_SIZE + 1):
+...     _ = Number.objects.create(num=num)
+
+>>> for i, obj in enumerate(Number.objects.all()):
+...     obj.save()
+...     if i > 10: break
+
 """}