summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/base.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-02-09 18:11:40 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2011-02-09 18:11:40 -0500
commit7e8f35109725ed3fd3caf96acf8b94a13c53fdfe (patch)
tree6ee96b736322eff04bb1ec5ff2b6e9de84e5545c /lib/sqlalchemy/engine/base.py
parente80eac22a8669ada5ffaabbcfa8a991eee140697 (diff)
downloadsqlalchemy-7e8f35109725ed3fd3caf96acf8b94a13c53fdfe.tar.gz
- Non-DBAPI errors which occur in the scope of an `execute()`
call are now wrapped in sqlalchemy.exc.StatementError, and the text of the SQL statement and repr() of params is included. This makes it easier to identify statement executions which fail before the DBAPI becomes involved. [ticket:2015]
Diffstat (limited to 'lib/sqlalchemy/engine/base.py')
-rw-r--r--lib/sqlalchemy/engine/base.py33
1 files changed, 23 insertions, 10 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index f6c974136..cf6c6ad49 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -1286,12 +1286,14 @@ class Connection(Connectable):
"""Execute a schema.DDL object."""
dialect = self.dialect
+
+ compiled = ddl.compile(dialect=dialect)
return self._execute_context(
dialect,
dialect.execution_ctx_cls._init_ddl,
- None,
+ compiled,
None,
- ddl.compile(dialect=dialect)
+ compiled
)
def _execute_clauseelement(self, elem, multiparams, params):
@@ -1322,7 +1324,7 @@ class Connection(Connectable):
return self._execute_context(
dialect,
dialect.execution_ctx_cls._init_compiled,
- None,
+ compiled_sql,
params,
compiled_sql, params
)
@@ -1335,7 +1337,7 @@ class Connection(Connectable):
return self._execute_context(
dialect,
dialect.execution_ctx_cls._init_compiled,
- None,
+ compiled,
parameters,
compiled, parameters
)
@@ -1357,7 +1359,8 @@ class Connection(Connectable):
_after_cursor_execute = None
def _execute_context(self, dialect, constructor,
- statement, parameters, *args):
+ statement, parameters,
+ *args):
"""Create an :class:`.ExecutionContext` and execute, returning
a :class:`.ResultProxy`."""
@@ -1370,7 +1373,7 @@ class Connection(Connectable):
context = constructor(dialect, self, conn, *args)
except Exception, e:
self._handle_dbapi_exception(e,
- statement, parameters,
+ str(statement), parameters,
None, None)
raise
@@ -1505,20 +1508,28 @@ class Connection(Connectable):
context):
if getattr(self, '_reentrant_error', False):
# Py3K
- #raise exc.DBAPIError.instance(statement, parameters, e) from e
+ #raise exc.DBAPIError.instance(statement, parameters, e,
+ # self.dialect.dbapi.Error) from e
# Py2K
- raise exc.DBAPIError.instance(statement, parameters, e), \
+ raise exc.DBAPIError.instance(statement,
+ parameters,
+ e,
+ self.dialect.dbapi.Error), \
None, sys.exc_info()[2]
# end Py2K
self._reentrant_error = True
try:
- if not isinstance(e, self.dialect.dbapi.Error):
+ # non-DBAPI error - if we already got a context,
+ # or theres no string statement, don't wrap it
+ if not isinstance(e, self.dialect.dbapi.Error) and \
+ (statement is None or context is not None):
return
if context:
context.handle_dbapi_exception(e)
- is_disconnect = self.dialect.is_disconnect(e, self.__connection, cursor)
+ is_disconnect = isinstance(e, self.dialect.dbapi.Error) and \
+ self.dialect.is_disconnect(e, self.__connection, cursor)
if is_disconnect:
self.invalidate(e)
self.engine.dispose()
@@ -1533,6 +1544,7 @@ class Connection(Connectable):
# statement,
# parameters,
# e,
+ # self.dialect.dbapi.Error,
# connection_invalidated=is_disconnect) \
# from e
# Py2K
@@ -1540,6 +1552,7 @@ class Connection(Connectable):
statement,
parameters,
e,
+ self.dialect.dbapi.Error,
connection_invalidated=is_disconnect), \
None, sys.exc_info()[2]
# end Py2K