78
79
class NoReferencedTableError(NoReferenceError):
79
80
"""Raised by ``ForeignKey`` when the referred ``Table`` cannot be located."""
82
def __init__(self, message, tname):
83
NoReferenceError.__init__(self, message)
84
self.table_name = tname
81
86
class NoReferencedColumnError(NoReferenceError):
82
87
"""Raised by ``ForeignKey`` when the referred ``Column`` cannot be located."""
89
def __init__(self, message, tname, cname):
90
NoReferenceError.__init__(self, message)
91
self.table_name = tname
92
self.column_name = cname
84
94
class NoSuchTableError(InvalidRequestError):
85
95
"""Table does not exist or is not visible to a connection."""
89
99
"""SQL was attempted without a database connection to execute it on."""
92
# Moved to orm.exc; compatability definition installed by orm import until 0.6
102
class DontWrapMixin(object):
103
"""A mixin class which, when applied to a user-defined Exception class,
104
will not be wrapped inside of :class:`.StatementError` if the error is
105
emitted within the process of executing a statement.
108
from sqlalchemy.exc import DontWrapMixin
110
class MyCustomException(Exception, DontWrapMixin):
113
class MySpecialType(TypeDecorator):
116
def process_bind_param(self, value, dialect):
117
if value == 'invalid':
118
raise MyCustomException("invalid!")
122
if sys.version_info < (2, 5):
126
# Moved to orm.exc; compatibility definition installed by orm import until 0.6
93
127
UnmappedColumnError = None
95
class DBAPIError(SQLAlchemyError):
129
class StatementError(SQLAlchemyError):
130
"""An error occurred during execution of a SQL statement.
132
:class:`.StatementError` wraps the exception raised
133
during execution, and features :attr:`.statement`
134
and :attr:`.params` attributes which supply context regarding
135
the specifics of the statement which had an issue.
137
The wrapped exception object is available in
138
the :attr:`.orig` attribute.
142
def __init__(self, message, statement, params, orig):
143
SQLAlchemyError.__init__(self, message)
144
self.statement = statement
149
if isinstance(self.params, (list, tuple)) and \
150
len(self.params) > 10 and \
151
isinstance(self.params[0], (list, dict, tuple)):
152
return ' '.join((SQLAlchemyError.__str__(self),
153
repr(self.statement),
154
repr(self.params[:2]),
155
'... and a total of %i bound parameter sets' % len(self.params)))
156
return ' '.join((SQLAlchemyError.__str__(self),
157
repr(self.statement), repr(self.params)))
159
class DBAPIError(StatementError):
96
160
"""Raised when the execution of a database operation fails.
98
162
``DBAPIError`` wraps exceptions raised by the DB-API underlying the
103
167
that there is no guarantee that different DB-API implementations will
104
168
raise the same exception type for any given error condition.
106
If the error-raising operation occured in the execution of a SQL
107
statement, that statement and its parameters will be available on
108
the exception object in the ``statement`` and ``params`` attributes.
170
:class:`.DBAPIError` features :attr:`.statement`
171
and :attr:`.params` attributes which supply context regarding
172
the specifics of the statement which had an issue, for the
173
typical case when the error was raised within the context of
174
emitting a SQL statement.
110
The wrapped exception object is available in the ``orig`` attribute.
176
The wrapped exception object is available in the :attr:`.orig` attribute.
111
177
Its type and properties are DB-API implementation specific.
116
def instance(cls, statement, params, orig, connection_invalidated=False):
182
def instance(cls, statement, params,
185
connection_invalidated=False):
117
186
# Don't ever wrap these, just return them directly as if
118
187
# DBAPIError didn't exist.
119
if isinstance(orig, (KeyboardInterrupt, SystemExit)):
188
if isinstance(orig, (KeyboardInterrupt, SystemExit, DontWrapMixin)):
122
191
if orig is not None:
192
# not a DBAPI error, statement is present.
193
# raise a StatementError
194
if not isinstance(orig, dbapi_base_err) and statement:
195
return StatementError(
196
"%s (original cause: %s)" % (
198
traceback.format_exception_only(orig.__class__, orig)[-1].strip()
199
), statement, params, orig)
123
201
name, glob = orig.__class__.__name__, globals()
124
202
if name in glob and issubclass(glob[name], DBAPIError):
134
212
except Exception, e:
135
213
text = 'Error in str() of DB-API-generated exception: ' + str(e)
136
SQLAlchemyError.__init__(
137
self, '(%s) %s' % (orig.__class__.__name__, text))
138
self.statement = statement
214
StatementError.__init__(
216
'(%s) %s' % (orig.__class__.__name__, text),
141
221
self.connection_invalidated = connection_invalidated
144
if isinstance(self.params, (list, tuple)) and len(self.params) > 10 and isinstance(self.params[0], (list, dict, tuple)):
145
return ' '.join((SQLAlchemyError.__str__(self),
146
repr(self.statement),
147
repr(self.params[:2]),
148
'... and a total of %i bound parameter sets' % len(self.params)))
149
return ' '.join((SQLAlchemyError.__str__(self),
150
repr(self.statement), repr(self.params)))
153
# As of 0.4, SQLError is now DBAPIError.
154
# SQLError alias will be removed in 0.6.
155
SQLError = DBAPIError
157
224
class InterfaceError(DBAPIError):
158
225
"""Wraps a DB-API InterfaceError."""