Code

Opened 5 years ago

Closed 5 years ago

Last modified 3 years ago

#10450 closed (fixed)

Savepoint should not assume an opened connection

Reported by: jdunck Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Using django transaction.savepoint() without having previously used a cursor fails if the backend actually supports savepoints.

e.g. Using postgres:

Python 2.5.2 (r252:60911, Mar 18 2008, 15:01:36) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from django.db import transaction
>>> transaction.savepoint()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jeremydunck/work/django/g-django/django/db/transaction.py", line 188, in savepoint
    connection._savepoint(sid)
  File "/Users/jeremydunck/work/django/g-django/django/db/backends/__init__.py", line 43, in _savepoint
    self.connection.cursor().execute(self.ops.savepoint_create_sql(sid))
AttributeError: 'NoneType' object has no attribute 'cursor'

It seems this problem has existed since savepoints were introduced, but I found it by trying to use the cached_db sessions backend.

In any case, the problem is that the savepoint family of methods on BaseDatabaseWrapper make the assumption that self.connection has been initiailized-- this is not a safe assumption. self.connection is initialized the first time BaseDatabaseWrapper.cursor is called, and that may not have happened before BaseDatabaseWrapper._savepoint*.

In all cases, ._savepoint* goes on to use connection.cursor, so I think it's safe to just use self.cursor() directly rather than self.connection.cursor().

Patch attached.

Unfortunately, I'm not sure how to make a test for this, because django's test suite itself uses django.db.connection.

At least it is easy to reproduce. :-)

Attachments (1)

savepoint_first.diff (1.0 KB) - added by jdunck 5 years ago.
Patch, no test.

Download all attachments as: .zip

Change History (5)

Changed 5 years ago by jdunck

Patch, no test.

comment:1 Changed 5 years ago by jacob

  • milestone set to 1.1
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

comment:2 Changed 5 years ago by Glenn

I was just bit by this, too, and I came up with an exactly identical patch.

It also fixes another bug: savepoint commands are hidden from the debug cursor, so they never show up in SQL logs.

comment:3 Changed 5 years ago by mtredinnick

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

(In [10512]) [1.0.X] Fixed #10450 -- Fixed an initialisation problem in the savepoint code.

Patch from Jeremy Dunck.

Backport of r10511 from trunk.

comment:4 Changed 3 years ago by jacob

  • milestone 1.1 deleted

Milestone 1.1 deleted

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.