Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/SQLAlchemy-1.3.25.dev0-py3.11-linux-x86_64.egg/sqlalchemy/exc.py: 67%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

171 statements  

1# sqlalchemy/exc.py 

2# Copyright (C) 2005-2021 the SQLAlchemy authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of SQLAlchemy and is released under 

6# the MIT License: http://www.opensource.org/licenses/mit-license.php 

7 

8"""Exceptions used with SQLAlchemy. 

9 

10The base exception class is :exc:`.SQLAlchemyError`. Exceptions which are 

11raised as a result of DBAPI exceptions are all subclasses of 

12:exc:`.DBAPIError`. 

13 

14""" 

15 

16from .util import _preloaded 

17from .util import compat 

18 

19_version_token = None 

20 

21 

22class SQLAlchemyError(Exception): 

23 """Generic error class.""" 

24 

25 code = None 

26 

27 def __init__(self, *arg, **kw): 

28 code = kw.pop("code", None) 

29 if code is not None: 

30 self.code = code 

31 super(SQLAlchemyError, self).__init__(*arg, **kw) 

32 

33 def _code_str(self): 

34 if not self.code: 

35 return "" 

36 else: 

37 return ( 

38 "(Background on this error at: " 

39 "http://sqlalche.me/e/%s/%s)" 

40 % ( 

41 _version_token, 

42 self.code, 

43 ) 

44 ) 

45 

46 def _message(self, as_unicode=compat.py3k): 

47 # rules: 

48 # 

49 # 1. under py2k, for __str__ return single string arg as it was 

50 # given without converting to unicode. for __unicode__ 

51 # do a conversion but check that it's not unicode already just in 

52 # case 

53 # 

54 # 2. under py3k, single arg string will usually be a unicode 

55 # object, but since __str__() must return unicode, check for 

56 # bytestring just in case 

57 # 

58 # 3. for multiple self.args, this is not a case in current 

59 # SQLAlchemy though this is happening in at least one known external 

60 # library, call str() which does a repr(). 

61 # 

62 if len(self.args) == 1: 

63 text = self.args[0] 

64 

65 if as_unicode and isinstance(text, compat.binary_types): 

66 text = compat.decode_backslashreplace(text, "utf-8") 

67 # This is for when the argument is not a string of any sort. 

68 # Otherwise, converting this exception to string would fail for 

69 # non-string arguments. 

70 elif compat.py3k or not as_unicode: 

71 text = str(text) 

72 else: 

73 text = compat.text_type(text) 

74 

75 return text 

76 else: 

77 # this is not a normal case within SQLAlchemy but is here for 

78 # compatibility with Exception.args - the str() comes out as 

79 # a repr() of the tuple 

80 return str(self.args) 

81 

82 def _sql_message(self, as_unicode): 

83 message = self._message(as_unicode) 

84 

85 if self.code: 

86 message = "%s %s" % (message, self._code_str()) 

87 

88 return message 

89 

90 def __str__(self): 

91 return self._sql_message(compat.py3k) 

92 

93 def __unicode__(self): 

94 return self._sql_message(as_unicode=True) 

95 

96 

97class ArgumentError(SQLAlchemyError): 

98 """Raised when an invalid or conflicting function argument is supplied. 

99 

100 This error generally corresponds to construction time state errors. 

101 

102 """ 

103 

104 

105class ObjectNotExecutableError(ArgumentError): 

106 """Raised when an object is passed to .execute() that can't be 

107 executed as SQL. 

108 

109 .. versionadded:: 1.1 

110 

111 """ 

112 

113 def __init__(self, target): 

114 super(ObjectNotExecutableError, self).__init__( 

115 "Not an executable object: %r" % target 

116 ) 

117 

118 

119class NoSuchModuleError(ArgumentError): 

120 """Raised when a dynamically-loaded module (usually a database dialect) 

121 of a particular name cannot be located.""" 

122 

123 

124class NoForeignKeysError(ArgumentError): 

125 """Raised when no foreign keys can be located between two selectables 

126 during a join.""" 

127 

128 

129class AmbiguousForeignKeysError(ArgumentError): 

130 """Raised when more than one foreign key matching can be located 

131 between two selectables during a join.""" 

132 

133 

134class CircularDependencyError(SQLAlchemyError): 

135 """Raised by topological sorts when a circular dependency is detected. 

136 

137 There are two scenarios where this error occurs: 

138 

139 * In a Session flush operation, if two objects are mutually dependent 

140 on each other, they can not be inserted or deleted via INSERT or 

141 DELETE statements alone; an UPDATE will be needed to post-associate 

142 or pre-deassociate one of the foreign key constrained values. 

143 The ``post_update`` flag described at :ref:`post_update` can resolve 

144 this cycle. 

145 * In a :attr:`_schema.MetaData.sorted_tables` operation, two 

146 :class:`_schema.ForeignKey` 

147 or :class:`_schema.ForeignKeyConstraint` objects mutually refer to each 

148 other. Apply the ``use_alter=True`` flag to one or both, 

149 see :ref:`use_alter`. 

150 

151 """ 

152 

153 def __init__(self, message, cycles, edges, msg=None, code=None): 

154 if msg is None: 

155 message += " (%s)" % ", ".join(repr(s) for s in cycles) 

156 else: 

157 message = msg 

158 SQLAlchemyError.__init__(self, message, code=code) 

159 self.cycles = cycles 

160 self.edges = edges 

161 

162 def __reduce__(self): 

163 return self.__class__, (None, self.cycles, self.edges, self.args[0]) 

164 

165 

166class CompileError(SQLAlchemyError): 

167 """Raised when an error occurs during SQL compilation""" 

168 

169 

170class UnsupportedCompilationError(CompileError): 

171 """Raised when an operation is not supported by the given compiler. 

172 

173 .. seealso:: 

174 

175 :ref:`faq_sql_expression_string` 

176 

177 :ref:`error_l7de` 

178 """ 

179 

180 code = "l7de" 

181 

182 def __init__(self, compiler, element_type, message=None): 

183 super(UnsupportedCompilationError, self).__init__( 

184 "Compiler %r can't render element of type %s%s" 

185 % (compiler, element_type, ": %s" % message if message else "") 

186 ) 

187 

188 

189class IdentifierError(SQLAlchemyError): 

190 """Raised when a schema name is beyond the max character limit""" 

191 

192 

193class DisconnectionError(SQLAlchemyError): 

194 """A disconnect is detected on a raw DB-API connection. 

195 

196 This error is raised and consumed internally by a connection pool. It can 

197 be raised by the :meth:`_events.PoolEvents.checkout` 

198 event so that the host pool 

199 forces a retry; the exception will be caught three times in a row before 

200 the pool gives up and raises :class:`~sqlalchemy.exc.InvalidRequestError` 

201 regarding the connection attempt. 

202 

203 """ 

204 

205 invalidate_pool = False 

206 

207 

208class InvalidatePoolError(DisconnectionError): 

209 """Raised when the connection pool should invalidate all stale connections. 

210 

211 A subclass of :class:`_exc.DisconnectionError` that indicates that the 

212 disconnect situation encountered on the connection probably means the 

213 entire pool should be invalidated, as the database has been restarted. 

214 

215 This exception will be handled otherwise the same way as 

216 :class:`_exc.DisconnectionError`, allowing three attempts to reconnect 

217 before giving up. 

218 

219 .. versionadded:: 1.2 

220 

221 """ 

222 

223 invalidate_pool = True 

224 

225 

226class TimeoutError(SQLAlchemyError): # noqa 

227 """Raised when a connection pool times out on getting a connection.""" 

228 

229 

230class InvalidRequestError(SQLAlchemyError): 

231 """SQLAlchemy was asked to do something it can't do. 

232 

233 This error generally corresponds to runtime state errors. 

234 

235 """ 

236 

237 

238class NoInspectionAvailable(InvalidRequestError): 

239 """A subject passed to :func:`sqlalchemy.inspection.inspect` produced 

240 no context for inspection.""" 

241 

242 

243class ResourceClosedError(InvalidRequestError): 

244 """An operation was requested from a connection, cursor, or other 

245 object that's in a closed state.""" 

246 

247 

248class NoSuchColumnError(KeyError, InvalidRequestError): 

249 """A nonexistent column is requested from a ``RowProxy``.""" 

250 

251 

252class NoReferenceError(InvalidRequestError): 

253 """Raised by ``ForeignKey`` to indicate a reference cannot be resolved.""" 

254 

255 

256class NoReferencedTableError(NoReferenceError): 

257 """Raised by ``ForeignKey`` when the referred ``Table`` cannot be 

258 located. 

259 

260 """ 

261 

262 def __init__(self, message, tname): 

263 NoReferenceError.__init__(self, message) 

264 self.table_name = tname 

265 

266 def __reduce__(self): 

267 return self.__class__, (self.args[0], self.table_name) 

268 

269 

270class NoReferencedColumnError(NoReferenceError): 

271 """Raised by ``ForeignKey`` when the referred ``Column`` cannot be 

272 located. 

273 

274 """ 

275 

276 def __init__(self, message, tname, cname): 

277 NoReferenceError.__init__(self, message) 

278 self.table_name = tname 

279 self.column_name = cname 

280 

281 def __reduce__(self): 

282 return ( 

283 self.__class__, 

284 (self.args[0], self.table_name, self.column_name), 

285 ) 

286 

287 

288class NoSuchTableError(InvalidRequestError): 

289 """Table does not exist or is not visible to a connection.""" 

290 

291 

292class UnreflectableTableError(InvalidRequestError): 

293 """Table exists but can't be reflected for some reason. 

294 

295 .. versionadded:: 1.2 

296 

297 """ 

298 

299 

300class UnboundExecutionError(InvalidRequestError): 

301 """SQL was attempted without a database connection to execute it on.""" 

302 

303 

304class DontWrapMixin(object): 

305 """A mixin class which, when applied to a user-defined Exception class, 

306 will not be wrapped inside of :exc:`.StatementError` if the error is 

307 emitted within the process of executing a statement. 

308 

309 E.g.:: 

310 

311 from sqlalchemy.exc import DontWrapMixin 

312 

313 class MyCustomException(Exception, DontWrapMixin): 

314 pass 

315 

316 class MySpecialType(TypeDecorator): 

317 impl = String 

318 

319 def process_bind_param(self, value, dialect): 

320 if value == 'invalid': 

321 raise MyCustomException("invalid!") 

322 

323 """ 

324 

325 

326# Moved to orm.exc; compatibility definition installed by orm import until 0.6 

327UnmappedColumnError = None 

328 

329 

330class StatementError(SQLAlchemyError): 

331 """An error occurred during execution of a SQL statement. 

332 

333 :class:`StatementError` wraps the exception raised 

334 during execution, and features :attr:`.statement` 

335 and :attr:`.params` attributes which supply context regarding 

336 the specifics of the statement which had an issue. 

337 

338 The wrapped exception object is available in 

339 the :attr:`.orig` attribute. 

340 

341 """ 

342 

343 statement = None 

344 """The string SQL statement being invoked when this exception occurred.""" 

345 

346 params = None 

347 """The parameter list being used when this exception occurred.""" 

348 

349 orig = None 

350 """The DBAPI exception object.""" 

351 

352 ismulti = None 

353 

354 def __init__( 

355 self, 

356 message, 

357 statement, 

358 params, 

359 orig, 

360 hide_parameters=False, 

361 code=None, 

362 ismulti=None, 

363 ): 

364 SQLAlchemyError.__init__(self, message, code=code) 

365 self.statement = statement 

366 self.params = params 

367 self.orig = orig 

368 self.ismulti = ismulti 

369 self.hide_parameters = hide_parameters 

370 self.detail = [] 

371 

372 def add_detail(self, msg): 

373 self.detail.append(msg) 

374 

375 def __reduce__(self): 

376 return ( 

377 self.__class__, 

378 ( 

379 self.args[0], 

380 self.statement, 

381 self.params, 

382 self.orig, 

383 self.hide_parameters, 

384 self.ismulti, 

385 ), 

386 ) 

387 

388 @_preloaded.dependencies("sqlalchemy.sql.util") 

389 def _sql_message(self, util, as_unicode): 

390 

391 details = [self._message(as_unicode=as_unicode)] 

392 if self.statement: 

393 if not as_unicode and not compat.py3k: 

394 stmt_detail = "[SQL: %s]" % compat.safe_bytestring( 

395 self.statement 

396 ) 

397 else: 

398 stmt_detail = "[SQL: %s]" % self.statement 

399 details.append(stmt_detail) 

400 if self.params: 

401 if self.hide_parameters: 

402 details.append( 

403 "[SQL parameters hidden due to hide_parameters=True]" 

404 ) 

405 else: 

406 params_repr = util._repr_params( 

407 self.params, 10, ismulti=self.ismulti 

408 ) 

409 details.append("[parameters: %r]" % params_repr) 

410 code_str = self._code_str() 

411 if code_str: 

412 details.append(code_str) 

413 return "\n".join(["(%s)" % det for det in self.detail] + details) 

414 

415 

416class DBAPIError(StatementError): 

417 """Raised when the execution of a database operation fails. 

418 

419 Wraps exceptions raised by the DB-API underlying the 

420 database operation. Driver-specific implementations of the standard 

421 DB-API exception types are wrapped by matching sub-types of SQLAlchemy's 

422 :class:`DBAPIError` when possible. DB-API's ``Error`` type maps to 

423 :class:`DBAPIError` in SQLAlchemy, otherwise the names are identical. Note 

424 that there is no guarantee that different DB-API implementations will 

425 raise the same exception type for any given error condition. 

426 

427 :class:`DBAPIError` features :attr:`~.StatementError.statement` 

428 and :attr:`~.StatementError.params` attributes which supply context 

429 regarding the specifics of the statement which had an issue, for the 

430 typical case when the error was raised within the context of 

431 emitting a SQL statement. 

432 

433 The wrapped exception object is available in the 

434 :attr:`~.StatementError.orig` attribute. Its type and properties are 

435 DB-API implementation specific. 

436 

437 """ 

438 

439 code = "dbapi" 

440 

441 @classmethod 

442 def instance( 

443 cls, 

444 statement, 

445 params, 

446 orig, 

447 dbapi_base_err, 

448 hide_parameters=False, 

449 connection_invalidated=False, 

450 dialect=None, 

451 ismulti=None, 

452 ): 

453 # Don't ever wrap these, just return them directly as if 

454 # DBAPIError didn't exist. 

455 if ( 

456 isinstance(orig, BaseException) and not isinstance(orig, Exception) 

457 ) or isinstance(orig, DontWrapMixin): 

458 return orig 

459 

460 if orig is not None: 

461 # not a DBAPI error, statement is present. 

462 # raise a StatementError 

463 if isinstance(orig, SQLAlchemyError) and statement: 

464 return StatementError( 

465 "(%s.%s) %s" 

466 % ( 

467 orig.__class__.__module__, 

468 orig.__class__.__name__, 

469 orig.args[0], 

470 ), 

471 statement, 

472 params, 

473 orig, 

474 hide_parameters=hide_parameters, 

475 code=orig.code, 

476 ismulti=ismulti, 

477 ) 

478 elif not isinstance(orig, dbapi_base_err) and statement: 

479 return StatementError( 

480 "(%s.%s) %s" 

481 % ( 

482 orig.__class__.__module__, 

483 orig.__class__.__name__, 

484 orig, 

485 ), 

486 statement, 

487 params, 

488 orig, 

489 hide_parameters=hide_parameters, 

490 ismulti=ismulti, 

491 ) 

492 

493 glob = globals() 

494 for super_ in orig.__class__.__mro__: 

495 name = super_.__name__ 

496 if dialect: 

497 name = dialect.dbapi_exception_translation_map.get( 

498 name, name 

499 ) 

500 if name in glob and issubclass(glob[name], DBAPIError): 

501 cls = glob[name] 

502 break 

503 

504 return cls( 

505 statement, 

506 params, 

507 orig, 

508 connection_invalidated=connection_invalidated, 

509 hide_parameters=hide_parameters, 

510 code=cls.code, 

511 ismulti=ismulti, 

512 ) 

513 

514 def __reduce__(self): 

515 return ( 

516 self.__class__, 

517 ( 

518 self.statement, 

519 self.params, 

520 self.orig, 

521 self.hide_parameters, 

522 self.connection_invalidated, 

523 self.ismulti, 

524 ), 

525 ) 

526 

527 def __init__( 

528 self, 

529 statement, 

530 params, 

531 orig, 

532 hide_parameters=False, 

533 connection_invalidated=False, 

534 code=None, 

535 ismulti=None, 

536 ): 

537 try: 

538 text = str(orig) 

539 except Exception as e: 

540 text = "Error in str() of DB-API-generated exception: " + str(e) 

541 StatementError.__init__( 

542 self, 

543 "(%s.%s) %s" 

544 % (orig.__class__.__module__, orig.__class__.__name__, text), 

545 statement, 

546 params, 

547 orig, 

548 hide_parameters, 

549 code=code, 

550 ismulti=ismulti, 

551 ) 

552 self.connection_invalidated = connection_invalidated 

553 

554 

555class InterfaceError(DBAPIError): 

556 """Wraps a DB-API InterfaceError.""" 

557 

558 code = "rvf5" 

559 

560 

561class DatabaseError(DBAPIError): 

562 """Wraps a DB-API DatabaseError.""" 

563 

564 code = "4xp6" 

565 

566 

567class DataError(DatabaseError): 

568 """Wraps a DB-API DataError.""" 

569 

570 code = "9h9h" 

571 

572 

573class OperationalError(DatabaseError): 

574 """Wraps a DB-API OperationalError.""" 

575 

576 code = "e3q8" 

577 

578 

579class IntegrityError(DatabaseError): 

580 """Wraps a DB-API IntegrityError.""" 

581 

582 code = "gkpj" 

583 

584 

585class InternalError(DatabaseError): 

586 """Wraps a DB-API InternalError.""" 

587 

588 code = "2j85" 

589 

590 

591class ProgrammingError(DatabaseError): 

592 """Wraps a DB-API ProgrammingError.""" 

593 

594 code = "f405" 

595 

596 

597class NotSupportedError(DatabaseError): 

598 """Wraps a DB-API NotSupportedError.""" 

599 

600 code = "tw8g" 

601 

602 

603# Warnings 

604 

605 

606class SADeprecationWarning(DeprecationWarning): 

607 """Issued once per usage of a deprecated API.""" 

608 

609 

610class SAPendingDeprecationWarning(PendingDeprecationWarning): 

611 """Issued once per usage of a deprecated API.""" 

612 

613 

614class SAWarning(RuntimeWarning): 

615 """Issued at runtime."""