Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #21109 -- made db cursor error wrapping faster

  • Loading branch information...
commit 94001421321bd8808c4027a72aa32a1eef005764 1 parent 5abc43c
@akaariai akaariai authored
View
11 django/db/backends/__init__.py
@@ -122,29 +122,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 #####
@@ -484,6 +484,7 @@ def validate_thread_sharing(self):
##### Miscellaneous #####
+ @cached_property
def wrap_database_errors(self):
"""
Context manager and decorator that re-throws backend-specific database
View
16 django/db/backends/utils.py
@@ -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
@@ -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)
@@ -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()
View
3  django/db/utils.py
@@ -94,7 +94,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)
Please sign in to comment.
Something went wrong with that request. Please try again.