Skip to content

Commit

Permalink
[1.6.x] Fixed #21109 -- made db cursor error wrapping faster
Browse files Browse the repository at this point in the history
Backpatch of 9400142 from master.
  • Loading branch information
akaariai committed Sep 17, 2013
1 parent c0625a7 commit 5937f29
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
11 changes: 6 additions & 5 deletions django/db/backends/__init__.py
Expand Up @@ -120,29 +120,29 @@ def ensure_connection(self):
Guarantees that a connection to the database is established.
"""
if self.connection is None:
with self.wrap_database_errors():
with self.wrap_database_errors:
self.connect()

##### Backend-specific wrappers for PEP-249 connection methods #####

def _cursor(self):
self.ensure_connection()
with self.wrap_database_errors():
with self.wrap_database_errors:
return self.create_cursor()

def _commit(self):
if self.connection is not None:
with self.wrap_database_errors():
with self.wrap_database_errors:
return self.connection.commit()

def _rollback(self):
if self.connection is not None:
with self.wrap_database_errors():
with self.wrap_database_errors:
return self.connection.rollback()

def _close(self):
if self.connection is not None:
with self.wrap_database_errors():
with self.wrap_database_errors:
return self.connection.close()

##### Generic wrappers for PEP-249 connection methods #####
Expand Down Expand Up @@ -482,6 +482,7 @@ def validate_thread_sharing(self):

##### Miscellaneous #####

@cached_property
def wrap_database_errors(self):
"""
Context manager and decorator that re-throws backend-specific database
Expand Down
16 changes: 10 additions & 6 deletions django/db/backends/util.py
Expand Up @@ -19,13 +19,17 @@ def __init__(self, cursor, db):
self.cursor = cursor
self.db = db

SET_DIRTY_ATTRS = frozenset(['execute', 'executemany', 'callproc'])
WRAP_ERROR_ATTRS = frozenset([
'callproc', 'close', 'execute', 'executemany',
'fetchone', 'fetchmany', 'fetchall', 'nextset'])

def __getattr__(self, attr):
if attr in ('execute', 'executemany', 'callproc'):
if attr in CursorWrapper.SET_DIRTY_ATTRS:
self.db.set_dirty()
cursor_attr = getattr(self.cursor, attr)
if attr in ('callproc', 'close', 'execute', 'executemany',
'fetchone', 'fetchmany', 'fetchall', 'nextset'):
return self.db.wrap_database_errors()(cursor_attr)
if attr in CursorWrapper.WRAP_ERROR_ATTRS:
return self.db.wrap_database_errors(cursor_attr)
else:
return cursor_attr

Expand All @@ -39,7 +43,7 @@ def execute(self, sql, params=None):
self.db.set_dirty()
start = time()
try:
with self.db.wrap_database_errors():
with self.db.wrap_database_errors:
if params is None:
# params default might be backend specific
return self.cursor.execute(sql)
Expand All @@ -60,7 +64,7 @@ def executemany(self, sql, param_list):
self.db.set_dirty()
start = time()
try:
with self.db.wrap_database_errors():
with self.db.wrap_database_errors:
return self.cursor.executemany(sql, param_list)
finally:
stop = time()
Expand Down
3 changes: 2 additions & 1 deletion django/db/utils.py
Expand Up @@ -99,7 +99,8 @@ def __exit__(self, exc_type, exc_value, traceback):
six.reraise(dj_exc_type, dj_exc_value, traceback)

def __call__(self, func):
@wraps(func)
# Note that we are intentionally not using @wraps here for performance
# reasons. Refs #21109.
def inner(*args, **kwargs):
with self:
return func(*args, **kwargs)
Expand Down

0 comments on commit 5937f29

Please sign in to comment.