Opened 22 months ago

Closed 22 months ago

Last modified 22 months ago

#21235 closed Bug (fixed)

1.6: Suggest installing standalone pysqlite2 on Windows when using Python 2.6

Reported by: ramiro Owned by: nobody
Component: Documentation Version: 1.6-beta-1
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Running the stable/1.6.x tests on Windows with the latest official Python 2.6.6 binaries results on many errors:

----------------------------------------------------------------------
Ran 5880 tests in 212.012s

FAILED (failures=6, errors=482, skipped=577, expected failures=11)
Destroying test database for alias 'default'...
Destroying test database for alias 'other'...

Example of one of them:

======================================================================
ERROR: test_form_jump (django.contrib.formtools.tests.wizard.namedwizardtests.tests.NamedCookieWizardTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\django\contrib\formtools\tests\wizard\namedwizardtests\tests.py", line 19, in setUp
    self.testuser, created = User.objects.get_or_create(username='testuser1')
  File "C:\django\db\models\manager.py", line 154, in get_or_create
    return self.get_queryset().get_or_create(**kwargs)
  File "C:\django\db\models\query.py", line 388, in get_or_create
    six.reraise(*exc_info)
  File "C:\django\db\models\query.py", line 379, in get_or_create
    with transaction.atomic(using=self.db):
  File "C:\django\db\transaction.py", line 265, in __enter__
    sid = connection.savepoint()
  File "C:\django\db\backends\__init__.py", line 227, in savepoint
    self._savepoint(sid)
  File "C:\django\db\backends\__init__.py", line 197, in _savepoint
    self.cursor().execute(self.ops.savepoint_create_sql(sid))
  File "C:\django\db\backends\util.py", line 53, in execute
    return self.cursor.execute(sql, params)
  File "C:\django\db\utils.py", line 99, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\django\db\backends\util.py", line 51, in execute
    return self.cursor.execute(sql)
  File "C:\django\db\backends\sqlite3\base.py", line 444, in execute
    return Database.Cursor.execute(self, query)
OperationalError: near "SAVEPOINT": syntax error

This might be related to the versions of SQLite shared library and/or stdlib3 sqlite module shipped with these binaries:

C:\>c:\python26\python
Python 2.6.6 (r266:84297, Aug 24 2010, 18:46:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3
>>> print(sqlite3.sqlite_version)
3.5.9
>>> print(sqlite3.version)
2.4.1

According to our transactions document savepoint SQL syntax was added to SQLite3 in 3.6.8 (https://docs.djangoproject.com/en/1.6/topics/db/transactions/#savepoints-in-sqlite)

Installing the latest pysqlite2 official binaries available ffor Python 2.6 (unfortunately only for 32 bits) at http://code.google.com/p/pysqlite/downloads/detail?name=pysqlite-2.6.3.win32-py2.6.exe solves the problem (the remaining error and failure are unrelated):

----------------------------------------------------------------------
Ran 5880 tests in 207.032s

FAILED (failures=1, errors=1, skipped=530, expected failures=11)

Perhaps we need to add a note about this to the relevant document (https://docs.djangoproject.com/en/1.6/ref/databases/#sqlite-notes).

Change History (4)

comment:1 Changed 22 months ago by aaugustin

Are you able to test the following patch?

diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index ac2376a..ef21423 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -393,12 +393,16 @@ class DatabaseWrapper(BaseDatabaseWrapper):
             BaseDatabaseWrapper.close(self)
 
     def _savepoint_allowed(self):
+        # Two conditions are required here:
+        # - A sufficiently recent version of SQLite to support savepoints,
+        # - Being in a transaction, which can only happen inside 'atomic'.
+
         # When 'isolation_level' is not None, sqlite3 commits before each
         # savepoint; it's a bug. When it is None, savepoints don't make sense
-        # because autocommit is enabled. The only exception is inside atomic
-        # blocks. To work around that bug, on SQLite, atomic starts a
+        # because autocommit is enabled. The only exception is inside 'atomic'
+        # blocks. To work around that bug, on SQLite, 'atomic' starts a
         # transaction explicitly rather than simply disable autocommit.
-        return self.in_atomic_block
+        return self.features.uses_savepoints and self.in_atomic_block
 
     def _set_autocommit(self, autocommit):
         if autocommit:

comment:2 Changed 22 months ago by ramiro

  • Has patch set
  • Triage Stage changed from Unreviewed to Accepted

Tes, the proposed patch solves the reported problems.

comment:3 Changed 22 months ago by Aymeric Augustin <aymeric.augustin@…>

  • Resolution set to fixed
  • Status changed from new to closed

In b42f0665a8cc25869c8dbc7bb71927b7ea61f81c:

[1.6.x] Fixed #21235 -- Disabled savepoints for old versions of SQLite.

Thanks Ramiro for the report.

Backport of 91547772 from master.

comment:4 Changed 22 months ago by Aymeric Augustin <aymeric.augustin@…>

In 91547772e04e456f45c7ef86e1f76d087821c89d:

Fixed #21235 -- Disabled savepoints for old versions of SQLite.

Thanks Ramiro for the report.

Note: See TracTickets for help on using tickets.
Back to Top