Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/interfaces.py: 63%

173 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:35 +0000

1# engine/interfaces.py 

2# Copyright (C) 2005-2023 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: https://www.opensource.org/licenses/mit-license.php 

7 

8"""Define core interfaces used by the engine system.""" 

9 

10from .. import util 

11from ..sql.compiler import Compiled # noqa 

12from ..sql.compiler import TypeCompiler # noqa 

13from ..util.concurrency import await_only 

14 

15 

16class Dialect(object): 

17 """Define the behavior of a specific database and DB-API combination. 

18 

19 Any aspect of metadata definition, SQL query generation, 

20 execution, result-set handling, or anything else which varies 

21 between databases is defined under the general category of the 

22 Dialect. The Dialect acts as a factory for other 

23 database-specific object implementations including 

24 ExecutionContext, Compiled, DefaultGenerator, and TypeEngine. 

25 

26 .. note:: Third party dialects should not subclass :class:`.Dialect` 

27 directly. Instead, subclass :class:`.default.DefaultDialect` or 

28 descendant class. 

29 

30 All dialects include the following attributes. There are many other 

31 attributes that may be supported as well: 

32 

33 ``name`` 

34 identifying name for the dialect from a DBAPI-neutral point of view 

35 (i.e. 'sqlite') 

36 

37 ``driver`` 

38 identifying name for the dialect's DBAPI 

39 

40 ``positional`` 

41 True if the paramstyle for this Dialect is positional. 

42 

43 ``paramstyle`` 

44 the paramstyle to be used (some DB-APIs support multiple 

45 paramstyles). 

46 

47 ``encoding`` 

48 type of encoding to use for unicode, usually defaults to 

49 'utf-8'. 

50 

51 ``statement_compiler`` 

52 a :class:`.Compiled` class used to compile SQL statements 

53 

54 ``ddl_compiler`` 

55 a :class:`.Compiled` class used to compile DDL statements 

56 

57 ``server_version_info`` 

58 a tuple containing a version number for the DB backend in use. 

59 This value is only available for supporting dialects, and is 

60 typically populated during the initial connection to the database. 

61 

62 ``default_schema_name`` 

63 the name of the default schema. This value is only available for 

64 supporting dialects, and is typically populated during the 

65 initial connection to the database. 

66 

67 ``execution_ctx_cls`` 

68 a :class:`.ExecutionContext` class used to handle statement execution 

69 

70 ``execute_sequence_format`` 

71 either the 'tuple' or 'list' type, depending on what cursor.execute() 

72 accepts for the second argument (they vary). 

73 

74 ``preparer`` 

75 a :class:`~sqlalchemy.sql.compiler.IdentifierPreparer` class used to 

76 quote identifiers. 

77 

78 ``supports_alter`` 

79 ``True`` if the database supports ``ALTER TABLE`` - used only for 

80 generating foreign key constraints in certain circumstances 

81 

82 ``max_identifier_length`` 

83 The maximum length of identifier names. 

84 

85 ``supports_sane_rowcount`` 

86 Indicate whether the dialect properly implements rowcount for 

87 ``UPDATE`` and ``DELETE`` statements. 

88 

89 ``supports_sane_multi_rowcount`` 

90 Indicate whether the dialect properly implements rowcount for 

91 ``UPDATE`` and ``DELETE`` statements when executed via 

92 executemany. 

93 

94 ``preexecute_autoincrement_sequences`` 

95 True if 'implicit' primary key functions must be executed separately 

96 in order to get their value. This is currently oriented towards 

97 PostgreSQL. 

98 

99 ``implicit_returning`` 

100 use RETURNING or equivalent during INSERT execution in order to load 

101 newly generated primary keys and other column defaults in one execution, 

102 which are then available via inserted_primary_key. 

103 If an insert statement has returning() specified explicitly, 

104 the "implicit" functionality is not used and inserted_primary_key 

105 will not be available. 

106 

107 ``colspecs`` 

108 A dictionary of TypeEngine classes from sqlalchemy.types mapped 

109 to subclasses that are specific to the dialect class. This 

110 dictionary is class-level only and is not accessed from the 

111 dialect instance itself. 

112 

113 ``supports_default_values`` 

114 Indicates if the construct ``INSERT INTO tablename DEFAULT 

115 VALUES`` is supported 

116 

117 ``supports_sequences`` 

118 Indicates if the dialect supports CREATE SEQUENCE or similar. 

119 

120 ``sequences_optional`` 

121 If True, indicates if the "optional" flag on the Sequence() construct 

122 should signal to not generate a CREATE SEQUENCE. Applies only to 

123 dialects that support sequences. Currently used only to allow PostgreSQL 

124 SERIAL to be used on a column that specifies Sequence() for usage on 

125 other backends. 

126 

127 ``supports_native_enum`` 

128 Indicates if the dialect supports a native ENUM construct. 

129 This will prevent types.Enum from generating a CHECK 

130 constraint when that type is used. 

131 

132 ``supports_native_boolean`` 

133 Indicates if the dialect supports a native boolean construct. 

134 This will prevent types.Boolean from generating a CHECK 

135 constraint when that type is used. 

136 

137 ``dbapi_exception_translation_map`` 

138 A dictionary of names that will contain as values the names of 

139 pep-249 exceptions ("IntegrityError", "OperationalError", etc) 

140 keyed to alternate class names, to support the case where a 

141 DBAPI has exception classes that aren't named as they are 

142 referred to (e.g. IntegrityError = MyException). In the vast 

143 majority of cases this dictionary is empty. 

144 

145 .. versionadded:: 1.0.5 

146 

147 """ 

148 

149 _has_events = False 

150 

151 supports_statement_cache = True 

152 """indicates if this dialect supports caching. 

153 

154 All dialects that are compatible with statement caching should set this 

155 flag to True directly on each dialect class and subclass that supports 

156 it. SQLAlchemy tests that this flag is locally present on each dialect 

157 subclass before it will use statement caching. This is to provide 

158 safety for legacy or new dialects that are not yet fully tested to be 

159 compliant with SQL statement caching. 

160 

161 .. versionadded:: 1.4.5 

162 

163 .. seealso:: 

164 

165 :ref:`engine_thirdparty_caching` 

166 

167 """ 

168 

169 def create_connect_args(self, url): 

170 """Build DB-API compatible connection arguments. 

171 

172 Given a :class:`.URL` object, returns a tuple 

173 consisting of a ``(*args, **kwargs)`` suitable to send directly 

174 to the dbapi's connect function. The arguments are sent to the 

175 :meth:`.Dialect.connect` method which then runs the DBAPI-level 

176 ``connect()`` function. 

177 

178 The method typically makes use of the 

179 :meth:`.URL.translate_connect_args` 

180 method in order to generate a dictionary of options. 

181 

182 The default implementation is:: 

183 

184 def create_connect_args(self, url): 

185 opts = url.translate_connect_args() 

186 opts.update(url.query) 

187 return [[], opts] 

188 

189 :param url: a :class:`.URL` object 

190 

191 :return: a tuple of ``(*args, **kwargs)`` which will be passed to the 

192 :meth:`.Dialect.connect` method. 

193 

194 .. seealso:: 

195 

196 :meth:`.URL.translate_connect_args` 

197 

198 """ 

199 

200 raise NotImplementedError() 

201 

202 @classmethod 

203 def type_descriptor(cls, typeobj): 

204 """Transform a generic type to a dialect-specific type. 

205 

206 Dialect classes will usually use the 

207 :func:`_types.adapt_type` function in the types module to 

208 accomplish this. 

209 

210 The returned result is cached *per dialect class* so can 

211 contain no dialect-instance state. 

212 

213 """ 

214 

215 raise NotImplementedError() 

216 

217 def initialize(self, connection): 

218 """Called during strategized creation of the dialect with a 

219 connection. 

220 

221 Allows dialects to configure options based on server version info or 

222 other properties. 

223 

224 The connection passed here is a SQLAlchemy Connection object, 

225 with full capabilities. 

226 

227 The initialize() method of the base dialect should be called via 

228 super(). 

229 

230 .. note:: as of SQLAlchemy 1.4, this method is called **before** 

231 any :meth:`_engine.Dialect.on_connect` hooks are called. 

232 

233 """ 

234 

235 pass 

236 

237 def get_columns(self, connection, table_name, schema=None, **kw): 

238 """Return information about columns in `table_name`. 

239 

240 Given a :class:`_engine.Connection`, a string 

241 `table_name`, and an optional string `schema`, return column 

242 information as a list of dictionaries with these keys: 

243 

244 name 

245 the column's name 

246 

247 type 

248 [sqlalchemy.types#TypeEngine] 

249 

250 nullable 

251 boolean 

252 

253 default 

254 the column's default value 

255 

256 autoincrement 

257 boolean 

258 

259 sequence 

260 a dictionary of the form 

261 {'name' : str, 'start' :int, 'increment': int, 'minvalue': int, 

262 'maxvalue': int, 'nominvalue': bool, 'nomaxvalue': bool, 

263 'cycle': bool, 'cache': int, 'order': bool} 

264 

265 Additional column attributes may be present. 

266 """ 

267 

268 raise NotImplementedError() 

269 

270 def get_pk_constraint(self, connection, table_name, schema=None, **kw): 

271 """Return information about the primary key constraint on 

272 table_name`. 

273 

274 Given a :class:`_engine.Connection`, a string 

275 `table_name`, and an optional string `schema`, return primary 

276 key information as a dictionary with these keys: 

277 

278 constrained_columns 

279 a list of column names that make up the primary key 

280 

281 name 

282 optional name of the primary key constraint. 

283 

284 """ 

285 raise NotImplementedError() 

286 

287 def get_foreign_keys(self, connection, table_name, schema=None, **kw): 

288 """Return information about foreign_keys in `table_name`. 

289 

290 Given a :class:`_engine.Connection`, a string 

291 `table_name`, and an optional string `schema`, return foreign 

292 key information as a list of dicts with these keys: 

293 

294 name 

295 the constraint's name 

296 

297 constrained_columns 

298 a list of column names that make up the foreign key 

299 

300 referred_schema 

301 the name of the referred schema 

302 

303 referred_table 

304 the name of the referred table 

305 

306 referred_columns 

307 a list of column names in the referred table that correspond to 

308 constrained_columns 

309 """ 

310 

311 raise NotImplementedError() 

312 

313 def get_table_names(self, connection, schema=None, **kw): 

314 """Return a list of table names for `schema`.""" 

315 

316 raise NotImplementedError() 

317 

318 def get_temp_table_names(self, connection, schema=None, **kw): 

319 """Return a list of temporary table names on the given connection, 

320 if supported by the underlying backend. 

321 

322 """ 

323 

324 raise NotImplementedError() 

325 

326 def get_view_names(self, connection, schema=None, **kw): 

327 """Return a list of all view names available in the database. 

328 

329 :param schema: schema name to query, if not the default schema. 

330 """ 

331 

332 raise NotImplementedError() 

333 

334 def get_sequence_names(self, connection, schema=None, **kw): 

335 """Return a list of all sequence names available in the database. 

336 

337 :param schema: schema name to query, if not the default schema. 

338 

339 .. versionadded:: 1.4 

340 """ 

341 

342 raise NotImplementedError() 

343 

344 def get_temp_view_names(self, connection, schema=None, **kw): 

345 """Return a list of temporary view names on the given connection, 

346 if supported by the underlying backend. 

347 

348 """ 

349 

350 raise NotImplementedError() 

351 

352 def get_view_definition(self, connection, view_name, schema=None, **kw): 

353 """Return view definition. 

354 

355 Given a :class:`_engine.Connection`, a string 

356 `view_name`, and an optional string `schema`, return the view 

357 definition. 

358 """ 

359 

360 raise NotImplementedError() 

361 

362 def get_indexes(self, connection, table_name, schema=None, **kw): 

363 """Return information about indexes in `table_name`. 

364 

365 Given a :class:`_engine.Connection`, a string 

366 `table_name` and an optional string `schema`, return index 

367 information as a list of dictionaries with these keys: 

368 

369 name 

370 the index's name 

371 

372 column_names 

373 list of column names in order 

374 

375 unique 

376 boolean 

377 """ 

378 

379 raise NotImplementedError() 

380 

381 def get_unique_constraints( 

382 self, connection, table_name, schema=None, **kw 

383 ): 

384 r"""Return information about unique constraints in `table_name`. 

385 

386 Given a string `table_name` and an optional string `schema`, return 

387 unique constraint information as a list of dicts with these keys: 

388 

389 name 

390 the unique constraint's name 

391 

392 column_names 

393 list of column names in order 

394 

395 \**kw 

396 other options passed to the dialect's get_unique_constraints() 

397 method. 

398 

399 .. versionadded:: 0.9.0 

400 

401 """ 

402 

403 raise NotImplementedError() 

404 

405 def get_check_constraints(self, connection, table_name, schema=None, **kw): 

406 r"""Return information about check constraints in `table_name`. 

407 

408 Given a string `table_name` and an optional string `schema`, return 

409 check constraint information as a list of dicts with these keys: 

410 

411 * ``name`` - 

412 the check constraint's name 

413 

414 * ``sqltext`` - 

415 the check constraint's SQL expression 

416 

417 * ``**kw`` - 

418 other options passed to the dialect's get_check_constraints() 

419 method. 

420 

421 .. versionadded:: 1.1.0 

422 

423 """ 

424 

425 raise NotImplementedError() 

426 

427 def get_table_comment(self, connection, table_name, schema=None, **kw): 

428 r"""Return the "comment" for the table identified by `table_name`. 

429 

430 Given a string `table_name` and an optional string `schema`, return 

431 table comment information as a dictionary with this key: 

432 

433 text 

434 text of the comment 

435 

436 Raises ``NotImplementedError`` for dialects that don't support 

437 comments. 

438 

439 .. versionadded:: 1.2 

440 

441 """ 

442 

443 raise NotImplementedError() 

444 

445 def normalize_name(self, name): 

446 """convert the given name to lowercase if it is detected as 

447 case insensitive. 

448 

449 This method is only used if the dialect defines 

450 requires_name_normalize=True. 

451 

452 """ 

453 raise NotImplementedError() 

454 

455 def denormalize_name(self, name): 

456 """convert the given name to a case insensitive identifier 

457 for the backend if it is an all-lowercase name. 

458 

459 This method is only used if the dialect defines 

460 requires_name_normalize=True. 

461 

462 """ 

463 raise NotImplementedError() 

464 

465 def has_table(self, connection, table_name, schema=None, **kw): 

466 """For internal dialect use, check the existence of a particular table 

467 in the database. 

468 

469 Given a :class:`_engine.Connection` object, a string table_name and 

470 optional schema name, return True if the given table exists in the 

471 database, False otherwise. 

472 

473 This method serves as the underlying implementation of the 

474 public facing :meth:`.Inspector.has_table` method, and is also used 

475 internally to implement the "checkfirst" behavior for methods like 

476 :meth:`_schema.Table.create` and :meth:`_schema.MetaData.create_all`. 

477 

478 .. note:: This method is used internally by SQLAlchemy, and is 

479 published so that third-party dialects may provide an 

480 implementation. It is **not** the public API for checking for table 

481 presence. Please use the :meth:`.Inspector.has_table` method. 

482 Alternatively, for legacy cross-compatibility, the 

483 :meth:`_engine.Engine.has_table` method may be used. 

484 

485 """ 

486 

487 raise NotImplementedError() 

488 

489 def has_index(self, connection, table_name, index_name, schema=None): 

490 """Check the existence of a particular index name in the database. 

491 

492 Given a :class:`_engine.Connection` object, a string 

493 `table_name` and string index name, return True if an index of the 

494 given name on the given table exists, false otherwise. 

495 

496 The :class:`.DefaultDialect` implements this in terms of the 

497 :meth:`.Dialect.has_table` and :meth:`.Dialect.get_indexes` methods, 

498 however dialects can implement a more performant version. 

499 

500 

501 .. versionadded:: 1.4 

502 

503 """ 

504 

505 raise NotImplementedError() 

506 

507 def has_sequence(self, connection, sequence_name, schema=None, **kw): 

508 """Check the existence of a particular sequence in the database. 

509 

510 Given a :class:`_engine.Connection` object and a string 

511 `sequence_name`, return True if the given sequence exists in 

512 the database, False otherwise. 

513 """ 

514 

515 raise NotImplementedError() 

516 

517 def _get_server_version_info(self, connection): 

518 """Retrieve the server version info from the given connection. 

519 

520 This is used by the default implementation to populate the 

521 "server_version_info" attribute and is called exactly 

522 once upon first connect. 

523 

524 """ 

525 

526 raise NotImplementedError() 

527 

528 def _get_default_schema_name(self, connection): 

529 """Return the string name of the currently selected schema from 

530 the given connection. 

531 

532 This is used by the default implementation to populate the 

533 "default_schema_name" attribute and is called exactly 

534 once upon first connect. 

535 

536 """ 

537 

538 raise NotImplementedError() 

539 

540 def do_begin(self, dbapi_connection): 

541 """Provide an implementation of ``connection.begin()``, given a 

542 DB-API connection. 

543 

544 The DBAPI has no dedicated "begin" method and it is expected 

545 that transactions are implicit. This hook is provided for those 

546 DBAPIs that might need additional help in this area. 

547 

548 Note that :meth:`.Dialect.do_begin` is not called unless a 

549 :class:`.Transaction` object is in use. The 

550 :meth:`.Dialect.do_autocommit` 

551 hook is provided for DBAPIs that need some extra commands emitted 

552 after a commit in order to enter the next transaction, when the 

553 SQLAlchemy :class:`_engine.Connection` 

554 is used in its default "autocommit" 

555 mode. 

556 

557 :param dbapi_connection: a DBAPI connection, typically 

558 proxied within a :class:`.ConnectionFairy`. 

559 

560 """ 

561 

562 raise NotImplementedError() 

563 

564 def do_rollback(self, dbapi_connection): 

565 """Provide an implementation of ``connection.rollback()``, given 

566 a DB-API connection. 

567 

568 :param dbapi_connection: a DBAPI connection, typically 

569 proxied within a :class:`.ConnectionFairy`. 

570 

571 """ 

572 

573 raise NotImplementedError() 

574 

575 def do_commit(self, dbapi_connection): 

576 """Provide an implementation of ``connection.commit()``, given a 

577 DB-API connection. 

578 

579 :param dbapi_connection: a DBAPI connection, typically 

580 proxied within a :class:`.ConnectionFairy`. 

581 

582 """ 

583 

584 raise NotImplementedError() 

585 

586 def do_terminate(self, dbapi_connection): 

587 """Provide an implementation of ``connection.close()`` that tries as 

588 much as possible to not block, given a DBAPI 

589 connection. 

590 

591 In the vast majority of cases this just calls .close(), however 

592 for some asyncio dialects may call upon different API features. 

593 

594 This hook is called by the :class:`_pool.Pool` 

595 when a connection is being recycled or has been invalidated. 

596 

597 .. versionadded:: 1.4.41 

598 

599 """ 

600 

601 raise NotImplementedError() 

602 

603 def do_close(self, dbapi_connection): 

604 """Provide an implementation of ``connection.close()``, given a DBAPI 

605 connection. 

606 

607 This hook is called by the :class:`_pool.Pool` 

608 when a connection has been 

609 detached from the pool, or is being returned beyond the normal 

610 capacity of the pool. 

611 

612 """ 

613 

614 raise NotImplementedError() 

615 

616 def do_set_input_sizes(self, cursor, list_of_tuples, context): 

617 """invoke the cursor.setinputsizes() method with appropriate arguments 

618 

619 This hook is called if the dialect.use_inputsizes flag is set to True. 

620 Parameter data is passed in a list of tuples (paramname, dbtype, 

621 sqltype), where ``paramname`` is the key of the parameter in the 

622 statement, ``dbtype`` is the DBAPI datatype and ``sqltype`` is the 

623 SQLAlchemy type. The order of tuples is in the correct parameter order. 

624 

625 .. versionadded:: 1.4 

626 

627 

628 """ 

629 raise NotImplementedError() 

630 

631 def create_xid(self): 

632 """Create a two-phase transaction ID. 

633 

634 This id will be passed to do_begin_twophase(), 

635 do_rollback_twophase(), do_commit_twophase(). Its format is 

636 unspecified. 

637 """ 

638 

639 raise NotImplementedError() 

640 

641 def do_savepoint(self, connection, name): 

642 """Create a savepoint with the given name. 

643 

644 :param connection: a :class:`_engine.Connection`. 

645 :param name: savepoint name. 

646 

647 """ 

648 

649 raise NotImplementedError() 

650 

651 def do_rollback_to_savepoint(self, connection, name): 

652 """Rollback a connection to the named savepoint. 

653 

654 :param connection: a :class:`_engine.Connection`. 

655 :param name: savepoint name. 

656 

657 """ 

658 

659 raise NotImplementedError() 

660 

661 def do_release_savepoint(self, connection, name): 

662 """Release the named savepoint on a connection. 

663 

664 :param connection: a :class:`_engine.Connection`. 

665 :param name: savepoint name. 

666 """ 

667 

668 raise NotImplementedError() 

669 

670 def do_begin_twophase(self, connection, xid): 

671 """Begin a two phase transaction on the given connection. 

672 

673 :param connection: a :class:`_engine.Connection`. 

674 :param xid: xid 

675 

676 """ 

677 

678 raise NotImplementedError() 

679 

680 def do_prepare_twophase(self, connection, xid): 

681 """Prepare a two phase transaction on the given connection. 

682 

683 :param connection: a :class:`_engine.Connection`. 

684 :param xid: xid 

685 

686 """ 

687 

688 raise NotImplementedError() 

689 

690 def do_rollback_twophase( 

691 self, connection, xid, is_prepared=True, recover=False 

692 ): 

693 """Rollback a two phase transaction on the given connection. 

694 

695 :param connection: a :class:`_engine.Connection`. 

696 :param xid: xid 

697 :param is_prepared: whether or not 

698 :meth:`.TwoPhaseTransaction.prepare` was called. 

699 :param recover: if the recover flag was passed. 

700 

701 """ 

702 

703 raise NotImplementedError() 

704 

705 def do_commit_twophase( 

706 self, connection, xid, is_prepared=True, recover=False 

707 ): 

708 """Commit a two phase transaction on the given connection. 

709 

710 

711 :param connection: a :class:`_engine.Connection`. 

712 :param xid: xid 

713 :param is_prepared: whether or not 

714 :meth:`.TwoPhaseTransaction.prepare` was called. 

715 :param recover: if the recover flag was passed. 

716 

717 """ 

718 

719 raise NotImplementedError() 

720 

721 def do_recover_twophase(self, connection): 

722 """Recover list of uncommitted prepared two phase transaction 

723 identifiers on the given connection. 

724 

725 :param connection: a :class:`_engine.Connection`. 

726 

727 """ 

728 

729 raise NotImplementedError() 

730 

731 def do_executemany(self, cursor, statement, parameters, context=None): 

732 """Provide an implementation of ``cursor.executemany(statement, 

733 parameters)``.""" 

734 

735 raise NotImplementedError() 

736 

737 def do_execute(self, cursor, statement, parameters, context=None): 

738 """Provide an implementation of ``cursor.execute(statement, 

739 parameters)``.""" 

740 

741 raise NotImplementedError() 

742 

743 def do_execute_no_params( 

744 self, cursor, statement, parameters, context=None 

745 ): 

746 """Provide an implementation of ``cursor.execute(statement)``. 

747 

748 The parameter collection should not be sent. 

749 

750 """ 

751 

752 raise NotImplementedError() 

753 

754 def is_disconnect(self, e, connection, cursor): 

755 """Return True if the given DB-API error indicates an invalid 

756 connection""" 

757 

758 raise NotImplementedError() 

759 

760 def connect(self, *cargs, **cparams): 

761 r"""Establish a connection using this dialect's DBAPI. 

762 

763 The default implementation of this method is:: 

764 

765 def connect(self, *cargs, **cparams): 

766 return self.dbapi.connect(*cargs, **cparams) 

767 

768 The ``*cargs, **cparams`` parameters are generated directly 

769 from this dialect's :meth:`.Dialect.create_connect_args` method. 

770 

771 This method may be used for dialects that need to perform programmatic 

772 per-connection steps when a new connection is procured from the 

773 DBAPI. 

774 

775 

776 :param \*cargs: positional parameters returned from the 

777 :meth:`.Dialect.create_connect_args` method 

778 

779 :param \*\*cparams: keyword parameters returned from the 

780 :meth:`.Dialect.create_connect_args` method. 

781 

782 :return: a DBAPI connection, typically from the :pep:`249` module 

783 level ``.connect()`` function. 

784 

785 .. seealso:: 

786 

787 :meth:`.Dialect.create_connect_args` 

788 

789 :meth:`.Dialect.on_connect` 

790 

791 """ 

792 

793 def on_connect_url(self, url): 

794 """return a callable which sets up a newly created DBAPI connection. 

795 

796 This method is a new hook that supersedes the 

797 :meth:`_engine.Dialect.on_connect` method when implemented by a 

798 dialect. When not implemented by a dialect, it invokes the 

799 :meth:`_engine.Dialect.on_connect` method directly to maintain 

800 compatibility with existing dialects. There is no deprecation 

801 for :meth:`_engine.Dialect.on_connect` expected. 

802 

803 The callable should accept a single argument "conn" which is the 

804 DBAPI connection itself. The inner callable has no 

805 return value. 

806 

807 E.g.:: 

808 

809 class MyDialect(default.DefaultDialect): 

810 # ... 

811 

812 def on_connect_url(self, url): 

813 def do_on_connect(connection): 

814 connection.execute("SET SPECIAL FLAGS etc") 

815 

816 return do_on_connect 

817 

818 This is used to set dialect-wide per-connection options such as 

819 isolation modes, Unicode modes, etc. 

820 

821 This method differs from :meth:`_engine.Dialect.on_connect` in that 

822 it is passed the :class:`_engine.URL` object that's relevant to the 

823 connect args. Normally the only way to get this is from the 

824 :meth:`_engine.Dialect.on_connect` hook is to look on the 

825 :class:`_engine.Engine` itself, however this URL object may have been 

826 replaced by plugins. 

827 

828 .. note:: 

829 

830 The default implementation of 

831 :meth:`_engine.Dialect.on_connect_url` is to invoke the 

832 :meth:`_engine.Dialect.on_connect` method. Therefore if a dialect 

833 implements this method, the :meth:`_engine.Dialect.on_connect` 

834 method **will not be called** unless the overriding dialect calls 

835 it directly from here. 

836 

837 .. versionadded:: 1.4.3 added :meth:`_engine.Dialect.on_connect_url` 

838 which normally calls into :meth:`_engine.Dialect.on_connect`. 

839 

840 :param url: a :class:`_engine.URL` object representing the 

841 :class:`_engine.URL` that was passed to the 

842 :meth:`_engine.Dialect.create_connect_args` method. 

843 

844 :return: a callable that accepts a single DBAPI connection as an 

845 argument, or None. 

846 

847 .. seealso:: 

848 

849 :meth:`_engine.Dialect.on_connect` 

850 

851 """ 

852 return self.on_connect() 

853 

854 def on_connect(self): 

855 """return a callable which sets up a newly created DBAPI connection. 

856 

857 The callable should accept a single argument "conn" which is the 

858 DBAPI connection itself. The inner callable has no 

859 return value. 

860 

861 E.g.:: 

862 

863 class MyDialect(default.DefaultDialect): 

864 # ... 

865 

866 def on_connect(self): 

867 def do_on_connect(connection): 

868 connection.execute("SET SPECIAL FLAGS etc") 

869 

870 return do_on_connect 

871 

872 This is used to set dialect-wide per-connection options such as 

873 isolation modes, Unicode modes, etc. 

874 

875 The "do_on_connect" callable is invoked by using the 

876 :meth:`_events.PoolEvents.connect` event 

877 hook, then unwrapping the DBAPI connection and passing it into the 

878 callable. 

879 

880 .. versionchanged:: 1.4 the on_connect hook is no longer called twice 

881 for the first connection of a dialect. The on_connect hook is still 

882 called before the :meth:`_engine.Dialect.initialize` method however. 

883 

884 .. versionchanged:: 1.4.3 the on_connect hook is invoked from a new 

885 method on_connect_url that passes the URL that was used to create 

886 the connect args. Dialects can implement on_connect_url instead 

887 of on_connect if they need the URL object that was used for the 

888 connection in order to get additional context. 

889 

890 If None is returned, no event listener is generated. 

891 

892 :return: a callable that accepts a single DBAPI connection as an 

893 argument, or None. 

894 

895 .. seealso:: 

896 

897 :meth:`.Dialect.connect` - allows the DBAPI ``connect()`` sequence 

898 itself to be controlled. 

899 

900 :meth:`.Dialect.on_connect_url` - supersedes 

901 :meth:`.Dialect.on_connect` to also receive the 

902 :class:`_engine.URL` object in context. 

903 

904 """ 

905 return None 

906 

907 def reset_isolation_level(self, dbapi_conn): 

908 """Given a DBAPI connection, revert its isolation to the default. 

909 

910 Note that this is a dialect-level method which is used as part 

911 of the implementation of the :class:`_engine.Connection` and 

912 :class:`_engine.Engine` 

913 isolation level facilities; these APIs should be preferred for 

914 most typical use cases. 

915 

916 .. seealso:: 

917 

918 :meth:`_engine.Connection.get_isolation_level` 

919 - view current level 

920 

921 :attr:`_engine.Connection.default_isolation_level` 

922 - view default level 

923 

924 :paramref:`.Connection.execution_options.isolation_level` - 

925 set per :class:`_engine.Connection` isolation level 

926 

927 :paramref:`_sa.create_engine.isolation_level` - 

928 set per :class:`_engine.Engine` isolation level 

929 

930 """ 

931 

932 raise NotImplementedError() 

933 

934 def set_isolation_level(self, dbapi_conn, level): 

935 """Given a DBAPI connection, set its isolation level. 

936 

937 Note that this is a dialect-level method which is used as part 

938 of the implementation of the :class:`_engine.Connection` and 

939 :class:`_engine.Engine` 

940 isolation level facilities; these APIs should be preferred for 

941 most typical use cases. 

942 

943 .. seealso:: 

944 

945 :meth:`_engine.Connection.get_isolation_level` 

946 - view current level 

947 

948 :attr:`_engine.Connection.default_isolation_level` 

949 - view default level 

950 

951 :paramref:`.Connection.execution_options.isolation_level` - 

952 set per :class:`_engine.Connection` isolation level 

953 

954 :paramref:`_sa.create_engine.isolation_level` - 

955 set per :class:`_engine.Engine` isolation level 

956 

957 """ 

958 

959 raise NotImplementedError() 

960 

961 def get_isolation_level(self, dbapi_conn): 

962 """Given a DBAPI connection, return its isolation level. 

963 

964 When working with a :class:`_engine.Connection` object, 

965 the corresponding 

966 DBAPI connection may be procured using the 

967 :attr:`_engine.Connection.connection` accessor. 

968 

969 Note that this is a dialect-level method which is used as part 

970 of the implementation of the :class:`_engine.Connection` and 

971 :class:`_engine.Engine` isolation level facilities; 

972 these APIs should be preferred for most typical use cases. 

973 

974 

975 .. seealso:: 

976 

977 :meth:`_engine.Connection.get_isolation_level` 

978 - view current level 

979 

980 :attr:`_engine.Connection.default_isolation_level` 

981 - view default level 

982 

983 :paramref:`.Connection.execution_options.isolation_level` - 

984 set per :class:`_engine.Connection` isolation level 

985 

986 :paramref:`_sa.create_engine.isolation_level` - 

987 set per :class:`_engine.Engine` isolation level 

988 

989 

990 """ 

991 

992 raise NotImplementedError() 

993 

994 def get_default_isolation_level(self, dbapi_conn): 

995 """Given a DBAPI connection, return its isolation level, or 

996 a default isolation level if one cannot be retrieved. 

997 

998 This method may only raise NotImplementedError and 

999 **must not raise any other exception**, as it is used implicitly upon 

1000 first connect. 

1001 

1002 The method **must return a value** for a dialect that supports 

1003 isolation level settings, as this level is what will be reverted 

1004 towards when a per-connection isolation level change is made. 

1005 

1006 The method defaults to using the :meth:`.Dialect.get_isolation_level` 

1007 method unless overridden by a dialect. 

1008 

1009 .. versionadded:: 1.3.22 

1010 

1011 """ 

1012 raise NotImplementedError() 

1013 

1014 @classmethod 

1015 def get_dialect_cls(cls, url): 

1016 """Given a URL, return the :class:`.Dialect` that will be used. 

1017 

1018 This is a hook that allows an external plugin to provide functionality 

1019 around an existing dialect, by allowing the plugin to be loaded 

1020 from the url based on an entrypoint, and then the plugin returns 

1021 the actual dialect to be used. 

1022 

1023 By default this just returns the cls. 

1024 

1025 .. versionadded:: 1.0.3 

1026 

1027 """ 

1028 return cls 

1029 

1030 @classmethod 

1031 def load_provisioning(cls): 

1032 """set up the provision.py module for this dialect. 

1033 

1034 For dialects that include a provision.py module that sets up 

1035 provisioning followers, this method should initiate that process. 

1036 

1037 A typical implementation would be:: 

1038 

1039 @classmethod 

1040 def load_provisioning(cls): 

1041 __import__("mydialect.provision") 

1042 

1043 The default method assumes a module named ``provision.py`` inside 

1044 the owning package of the current dialect, based on the ``__module__`` 

1045 attribute:: 

1046 

1047 @classmethod 

1048 def load_provisioning(cls): 

1049 package = ".".join(cls.__module__.split(".")[0:-1]) 

1050 try: 

1051 __import__(package + ".provision") 

1052 except ImportError: 

1053 pass 

1054 

1055 .. versionadded:: 1.3.14 

1056 

1057 """ 

1058 

1059 @classmethod 

1060 def engine_created(cls, engine): 

1061 """A convenience hook called before returning the final 

1062 :class:`_engine.Engine`. 

1063 

1064 If the dialect returned a different class from the 

1065 :meth:`.get_dialect_cls` 

1066 method, then the hook is called on both classes, first on 

1067 the dialect class returned by the :meth:`.get_dialect_cls` method and 

1068 then on the class on which the method was called. 

1069 

1070 The hook should be used by dialects and/or wrappers to apply special 

1071 events to the engine or its components. In particular, it allows 

1072 a dialect-wrapping class to apply dialect-level events. 

1073 

1074 .. versionadded:: 1.0.3 

1075 

1076 """ 

1077 

1078 def get_driver_connection(self, connection): 

1079 """Returns the connection object as returned by the external driver 

1080 package. 

1081 

1082 For normal dialects that use a DBAPI compliant driver this call 

1083 will just return the ``connection`` passed as argument. 

1084 For dialects that instead adapt a non DBAPI compliant driver, like 

1085 when adapting an asyncio driver, this call will return the 

1086 connection-like object as returned by the driver. 

1087 

1088 .. versionadded:: 1.4.24 

1089 

1090 """ 

1091 raise NotImplementedError() 

1092 

1093 

1094class CreateEnginePlugin(object): 

1095 """A set of hooks intended to augment the construction of an 

1096 :class:`_engine.Engine` object based on entrypoint names in a URL. 

1097 

1098 The purpose of :class:`_engine.CreateEnginePlugin` is to allow third-party 

1099 systems to apply engine, pool and dialect level event listeners without 

1100 the need for the target application to be modified; instead, the plugin 

1101 names can be added to the database URL. Target applications for 

1102 :class:`_engine.CreateEnginePlugin` include: 

1103 

1104 * connection and SQL performance tools, e.g. which use events to track 

1105 number of checkouts and/or time spent with statements 

1106 

1107 * connectivity plugins such as proxies 

1108 

1109 A rudimentary :class:`_engine.CreateEnginePlugin` that attaches a logger 

1110 to an :class:`_engine.Engine` object might look like:: 

1111 

1112 

1113 import logging 

1114 

1115 from sqlalchemy.engine import CreateEnginePlugin 

1116 from sqlalchemy import event 

1117 

1118 class LogCursorEventsPlugin(CreateEnginePlugin): 

1119 def __init__(self, url, kwargs): 

1120 # consume the parameter "log_cursor_logging_name" from the 

1121 # URL query 

1122 logging_name = url.query.get("log_cursor_logging_name", "log_cursor") 

1123 

1124 self.log = logging.getLogger(logging_name) 

1125 

1126 def update_url(self, url): 

1127 "update the URL to one that no longer includes our parameters" 

1128 return url.difference_update_query(["log_cursor_logging_name"]) 

1129 

1130 def engine_created(self, engine): 

1131 "attach an event listener after the new Engine is constructed" 

1132 event.listen(engine, "before_cursor_execute", self._log_event) 

1133 

1134 

1135 def _log_event( 

1136 self, 

1137 conn, 

1138 cursor, 

1139 statement, 

1140 parameters, 

1141 context, 

1142 executemany): 

1143 

1144 self.log.info("Plugin logged cursor event: %s", statement) 

1145 

1146 

1147 

1148 Plugins are registered using entry points in a similar way as that 

1149 of dialects:: 

1150 

1151 entry_points={ 

1152 'sqlalchemy.plugins': [ 

1153 'log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin' 

1154 ] 

1155 

1156 A plugin that uses the above names would be invoked from a database 

1157 URL as in:: 

1158 

1159 from sqlalchemy import create_engine 

1160 

1161 engine = create_engine( 

1162 "mysql+pymysql://scott:tiger@localhost/test?" 

1163 "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger" 

1164 ) 

1165 

1166 The ``plugin`` URL parameter supports multiple instances, so that a URL 

1167 may specify multiple plugins; they are loaded in the order stated 

1168 in the URL:: 

1169 

1170 engine = create_engine( 

1171 "mysql+pymysql://scott:tiger@localhost/test?" 

1172 "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three") 

1173 

1174 The plugin names may also be passed directly to :func:`_sa.create_engine` 

1175 using the :paramref:`_sa.create_engine.plugins` argument:: 

1176 

1177 engine = create_engine( 

1178 "mysql+pymysql://scott:tiger@localhost/test", 

1179 plugins=["myplugin"]) 

1180 

1181 .. versionadded:: 1.2.3 plugin names can also be specified 

1182 to :func:`_sa.create_engine` as a list 

1183 

1184 A plugin may consume plugin-specific arguments from the 

1185 :class:`_engine.URL` object as well as the ``kwargs`` dictionary, which is 

1186 the dictionary of arguments passed to the :func:`_sa.create_engine` 

1187 call. "Consuming" these arguments includes that they must be removed 

1188 when the plugin initializes, so that the arguments are not passed along 

1189 to the :class:`_engine.Dialect` constructor, where they will raise an 

1190 :class:`_exc.ArgumentError` because they are not known by the dialect. 

1191 

1192 As of version 1.4 of SQLAlchemy, arguments should continue to be consumed 

1193 from the ``kwargs`` dictionary directly, by removing the values with a 

1194 method such as ``dict.pop``. Arguments from the :class:`_engine.URL` object 

1195 should be consumed by implementing the 

1196 :meth:`_engine.CreateEnginePlugin.update_url` method, returning a new copy 

1197 of the :class:`_engine.URL` with plugin-specific parameters removed:: 

1198 

1199 class MyPlugin(CreateEnginePlugin): 

1200 def __init__(self, url, kwargs): 

1201 self.my_argument_one = url.query['my_argument_one'] 

1202 self.my_argument_two = url.query['my_argument_two'] 

1203 self.my_argument_three = kwargs.pop('my_argument_three', None) 

1204 

1205 def update_url(self, url): 

1206 return url.difference_update_query( 

1207 ["my_argument_one", "my_argument_two"] 

1208 ) 

1209 

1210 Arguments like those illustrated above would be consumed from a 

1211 :func:`_sa.create_engine` call such as:: 

1212 

1213 from sqlalchemy import create_engine 

1214 

1215 engine = create_engine( 

1216 "mysql+pymysql://scott:tiger@localhost/test?" 

1217 "plugin=myplugin&my_argument_one=foo&my_argument_two=bar", 

1218 my_argument_three='bat' 

1219 ) 

1220 

1221 .. versionchanged:: 1.4 

1222 

1223 The :class:`_engine.URL` object is now immutable; a 

1224 :class:`_engine.CreateEnginePlugin` that needs to alter the 

1225 :class:`_engine.URL` should implement the newly added 

1226 :meth:`_engine.CreateEnginePlugin.update_url` method, which 

1227 is invoked after the plugin is constructed. 

1228 

1229 For migration, construct the plugin in the following way, checking 

1230 for the existence of the :meth:`_engine.CreateEnginePlugin.update_url` 

1231 method to detect which version is running:: 

1232 

1233 class MyPlugin(CreateEnginePlugin): 

1234 def __init__(self, url, kwargs): 

1235 if hasattr(CreateEnginePlugin, "update_url"): 

1236 # detect the 1.4 API 

1237 self.my_argument_one = url.query['my_argument_one'] 

1238 self.my_argument_two = url.query['my_argument_two'] 

1239 else: 

1240 # detect the 1.3 and earlier API - mutate the 

1241 # URL directly 

1242 self.my_argument_one = url.query.pop('my_argument_one') 

1243 self.my_argument_two = url.query.pop('my_argument_two') 

1244 

1245 self.my_argument_three = kwargs.pop('my_argument_three', None) 

1246 

1247 def update_url(self, url): 

1248 # this method is only called in the 1.4 version 

1249 return url.difference_update_query( 

1250 ["my_argument_one", "my_argument_two"] 

1251 ) 

1252 

1253 .. seealso:: 

1254 

1255 :ref:`change_5526` - overview of the :class:`_engine.URL` change which 

1256 also includes notes regarding :class:`_engine.CreateEnginePlugin`. 

1257 

1258 

1259 When the engine creation process completes and produces the 

1260 :class:`_engine.Engine` object, it is again passed to the plugin via the 

1261 :meth:`_engine.CreateEnginePlugin.engine_created` hook. In this hook, additional 

1262 changes can be made to the engine, most typically involving setup of 

1263 events (e.g. those defined in :ref:`core_event_toplevel`). 

1264 

1265 .. versionadded:: 1.1 

1266 

1267 """ # noqa: E501 

1268 

1269 def __init__(self, url, kwargs): 

1270 """Construct a new :class:`.CreateEnginePlugin`. 

1271 

1272 The plugin object is instantiated individually for each call 

1273 to :func:`_sa.create_engine`. A single :class:`_engine. 

1274 Engine` will be 

1275 passed to the :meth:`.CreateEnginePlugin.engine_created` method 

1276 corresponding to this URL. 

1277 

1278 :param url: the :class:`_engine.URL` object. The plugin may inspect 

1279 the :class:`_engine.URL` for arguments. Arguments used by the 

1280 plugin should be removed, by returning an updated :class:`_engine.URL` 

1281 from the :meth:`_engine.CreateEnginePlugin.update_url` method. 

1282 

1283 .. versionchanged:: 1.4 

1284 

1285 The :class:`_engine.URL` object is now immutable, so a 

1286 :class:`_engine.CreateEnginePlugin` that needs to alter the 

1287 :class:`_engine.URL` object should implement the 

1288 :meth:`_engine.CreateEnginePlugin.update_url` method. 

1289 

1290 :param kwargs: The keyword arguments passed to 

1291 :func:`_sa.create_engine`. 

1292 

1293 """ 

1294 self.url = url 

1295 

1296 def update_url(self, url): 

1297 """Update the :class:`_engine.URL`. 

1298 

1299 A new :class:`_engine.URL` should be returned. This method is 

1300 typically used to consume configuration arguments from the 

1301 :class:`_engine.URL` which must be removed, as they will not be 

1302 recognized by the dialect. The 

1303 :meth:`_engine.URL.difference_update_query` method is available 

1304 to remove these arguments. See the docstring at 

1305 :class:`_engine.CreateEnginePlugin` for an example. 

1306 

1307 

1308 .. versionadded:: 1.4 

1309 

1310 """ 

1311 

1312 def handle_dialect_kwargs(self, dialect_cls, dialect_args): 

1313 """parse and modify dialect kwargs""" 

1314 

1315 def handle_pool_kwargs(self, pool_cls, pool_args): 

1316 """parse and modify pool kwargs""" 

1317 

1318 def engine_created(self, engine): 

1319 """Receive the :class:`_engine.Engine` 

1320 object when it is fully constructed. 

1321 

1322 The plugin may make additional changes to the engine, such as 

1323 registering engine or connection pool events. 

1324 

1325 """ 

1326 

1327 

1328class ExecutionContext(object): 

1329 """A messenger object for a Dialect that corresponds to a single 

1330 execution. 

1331 

1332 ExecutionContext should have these data members: 

1333 

1334 connection 

1335 Connection object which can be freely used by default value 

1336 generators to execute SQL. This Connection should reference the 

1337 same underlying connection/transactional resources of 

1338 root_connection. 

1339 

1340 root_connection 

1341 Connection object which is the source of this ExecutionContext. This 

1342 Connection may have close_with_result=True set, in which case it can 

1343 only be used once. 

1344 

1345 dialect 

1346 dialect which created this ExecutionContext. 

1347 

1348 cursor 

1349 DB-API cursor procured from the connection, 

1350 

1351 compiled 

1352 if passed to constructor, sqlalchemy.engine.base.Compiled object 

1353 being executed, 

1354 

1355 statement 

1356 string version of the statement to be executed. Is either 

1357 passed to the constructor, or must be created from the 

1358 sql.Compiled object by the time pre_exec() has completed. 

1359 

1360 parameters 

1361 bind parameters passed to the execute() method. For compiled 

1362 statements, this is a dictionary or list of dictionaries. For 

1363 textual statements, it should be in a format suitable for the 

1364 dialect's paramstyle (i.e. dict or list of dicts for non 

1365 positional, list or list of lists/tuples for positional). 

1366 

1367 isinsert 

1368 True if the statement is an INSERT. 

1369 

1370 isupdate 

1371 True if the statement is an UPDATE. 

1372 

1373 should_autocommit 

1374 True if the statement is a "committable" statement. 

1375 

1376 prefetch_cols 

1377 a list of Column objects for which a client-side default 

1378 was fired off. Applies to inserts and updates. 

1379 

1380 postfetch_cols 

1381 a list of Column objects for which a server-side default or 

1382 inline SQL expression value was fired off. Applies to inserts 

1383 and updates. 

1384 """ 

1385 

1386 def create_cursor(self): 

1387 """Return a new cursor generated from this ExecutionContext's 

1388 connection. 

1389 

1390 Some dialects may wish to change the behavior of 

1391 connection.cursor(), such as postgresql which may return a PG 

1392 "server side" cursor. 

1393 """ 

1394 

1395 raise NotImplementedError() 

1396 

1397 def pre_exec(self): 

1398 """Called before an execution of a compiled statement. 

1399 

1400 If a compiled statement was passed to this ExecutionContext, 

1401 the `statement` and `parameters` datamembers must be 

1402 initialized after this statement is complete. 

1403 """ 

1404 

1405 raise NotImplementedError() 

1406 

1407 def get_out_parameter_values(self, out_param_names): 

1408 """Return a sequence of OUT parameter values from a cursor. 

1409 

1410 For dialects that support OUT parameters, this method will be called 

1411 when there is a :class:`.SQLCompiler` object which has the 

1412 :attr:`.SQLCompiler.has_out_parameters` flag set. This flag in turn 

1413 will be set to True if the statement itself has :class:`.BindParameter` 

1414 objects that have the ``.isoutparam`` flag set which are consumed by 

1415 the :meth:`.SQLCompiler.visit_bindparam` method. If the dialect 

1416 compiler produces :class:`.BindParameter` objects with ``.isoutparam`` 

1417 set which are not handled by :meth:`.SQLCompiler.visit_bindparam`, it 

1418 should set this flag explicitly. 

1419 

1420 The list of names that were rendered for each bound parameter 

1421 is passed to the method. The method should then return a sequence of 

1422 values corresponding to the list of parameter objects. Unlike in 

1423 previous SQLAlchemy versions, the values can be the **raw values** from 

1424 the DBAPI; the execution context will apply the appropriate type 

1425 handler based on what's present in self.compiled.binds and update the 

1426 values. The processed dictionary will then be made available via the 

1427 ``.out_parameters`` collection on the result object. Note that 

1428 SQLAlchemy 1.4 has multiple kinds of result object as part of the 2.0 

1429 transition. 

1430 

1431 .. versionadded:: 1.4 - added 

1432 :meth:`.ExecutionContext.get_out_parameter_values`, which is invoked 

1433 automatically by the :class:`.DefaultExecutionContext` when there 

1434 are :class:`.BindParameter` objects with the ``.isoutparam`` flag 

1435 set. This replaces the practice of setting out parameters within 

1436 the now-removed ``get_result_proxy()`` method. 

1437 

1438 """ 

1439 raise NotImplementedError() 

1440 

1441 def post_exec(self): 

1442 """Called after the execution of a compiled statement. 

1443 

1444 If a compiled statement was passed to this ExecutionContext, 

1445 the `last_insert_ids`, `last_inserted_params`, etc. 

1446 datamembers should be available after this method completes. 

1447 """ 

1448 

1449 raise NotImplementedError() 

1450 

1451 def handle_dbapi_exception(self, e): 

1452 """Receive a DBAPI exception which occurred upon execute, result 

1453 fetch, etc.""" 

1454 

1455 raise NotImplementedError() 

1456 

1457 def should_autocommit_text(self, statement): 

1458 """Parse the given textual statement and return True if it refers to 

1459 a "committable" statement""" 

1460 

1461 raise NotImplementedError() 

1462 

1463 def lastrow_has_defaults(self): 

1464 """Return True if the last INSERT or UPDATE row contained 

1465 inlined or database-side defaults. 

1466 """ 

1467 

1468 raise NotImplementedError() 

1469 

1470 def get_rowcount(self): 

1471 """Return the DBAPI ``cursor.rowcount`` value, or in some 

1472 cases an interpreted value. 

1473 

1474 See :attr:`_engine.CursorResult.rowcount` for details on this. 

1475 

1476 """ 

1477 

1478 raise NotImplementedError() 

1479 

1480 

1481@util.deprecated_20_cls( 

1482 ":class:`.Connectable`", 

1483 alternative=( 

1484 "The :class:`_engine.Engine` will be the only Core " 

1485 "object that features a .connect() method, and the " 

1486 ":class:`_engine.Connection` will be the only object that features " 

1487 "an .execute() method." 

1488 ), 

1489 constructor=None, 

1490) 

1491class Connectable(object): 

1492 """Interface for an object which supports execution of SQL constructs. 

1493 

1494 The two implementations of :class:`.Connectable` are 

1495 :class:`_engine.Connection` and :class:`_engine.Engine`. 

1496 

1497 Connectable must also implement the 'dialect' member which references a 

1498 :class:`.Dialect` instance. 

1499 

1500 """ 

1501 

1502 def connect(self, **kwargs): 

1503 """Return a :class:`_engine.Connection` object. 

1504 

1505 Depending on context, this may be ``self`` if this object 

1506 is already an instance of :class:`_engine.Connection`, or a newly 

1507 procured :class:`_engine.Connection` if this object is an instance 

1508 of :class:`_engine.Engine`. 

1509 

1510 """ 

1511 

1512 engine = None 

1513 """The :class:`_engine.Engine` instance referred to by this 

1514 :class:`.Connectable`. 

1515 

1516 May be ``self`` if this is already an :class:`_engine.Engine`. 

1517 

1518 """ 

1519 

1520 def execute(self, object_, *multiparams, **params): 

1521 """Executes the given construct and returns a 

1522 :class:`_engine.CursorResult`. 

1523 """ 

1524 raise NotImplementedError() 

1525 

1526 def scalar(self, object_, *multiparams, **params): 

1527 """Executes and returns the first column of the first row. 

1528 

1529 The underlying cursor is closed after execution. 

1530 """ 

1531 raise NotImplementedError() 

1532 

1533 def _run_visitor(self, visitorcallable, element, **kwargs): 

1534 raise NotImplementedError() 

1535 

1536 def _execute_clauseelement(self, elem, multiparams=None, params=None): 

1537 raise NotImplementedError() 

1538 

1539 

1540class ExceptionContext(object): 

1541 """Encapsulate information about an error condition in progress. 

1542 

1543 This object exists solely to be passed to the 

1544 :meth:`_events.ConnectionEvents.handle_error` event, 

1545 supporting an interface that 

1546 can be extended without backwards-incompatibility. 

1547 

1548 .. versionadded:: 0.9.7 

1549 

1550 """ 

1551 

1552 connection = None 

1553 """The :class:`_engine.Connection` in use during the exception. 

1554 

1555 This member is present, except in the case of a failure when 

1556 first connecting. 

1557 

1558 .. seealso:: 

1559 

1560 :attr:`.ExceptionContext.engine` 

1561 

1562 

1563 """ 

1564 

1565 engine = None 

1566 """The :class:`_engine.Engine` in use during the exception. 

1567 

1568 This member should always be present, even in the case of a failure 

1569 when first connecting. 

1570 

1571 .. versionadded:: 1.0.0 

1572 

1573 """ 

1574 

1575 cursor = None 

1576 """The DBAPI cursor object. 

1577 

1578 May be None. 

1579 

1580 """ 

1581 

1582 statement = None 

1583 """String SQL statement that was emitted directly to the DBAPI. 

1584 

1585 May be None. 

1586 

1587 """ 

1588 

1589 parameters = None 

1590 """Parameter collection that was emitted directly to the DBAPI. 

1591 

1592 May be None. 

1593 

1594 """ 

1595 

1596 original_exception = None 

1597 """The exception object which was caught. 

1598 

1599 This member is always present. 

1600 

1601 """ 

1602 

1603 sqlalchemy_exception = None 

1604 """The :class:`sqlalchemy.exc.StatementError` which wraps the original, 

1605 and will be raised if exception handling is not circumvented by the event. 

1606 

1607 May be None, as not all exception types are wrapped by SQLAlchemy. 

1608 For DBAPI-level exceptions that subclass the dbapi's Error class, this 

1609 field will always be present. 

1610 

1611 """ 

1612 

1613 chained_exception = None 

1614 """The exception that was returned by the previous handler in the 

1615 exception chain, if any. 

1616 

1617 If present, this exception will be the one ultimately raised by 

1618 SQLAlchemy unless a subsequent handler replaces it. 

1619 

1620 May be None. 

1621 

1622 """ 

1623 

1624 execution_context = None 

1625 """The :class:`.ExecutionContext` corresponding to the execution 

1626 operation in progress. 

1627 

1628 This is present for statement execution operations, but not for 

1629 operations such as transaction begin/end. It also is not present when 

1630 the exception was raised before the :class:`.ExecutionContext` 

1631 could be constructed. 

1632 

1633 Note that the :attr:`.ExceptionContext.statement` and 

1634 :attr:`.ExceptionContext.parameters` members may represent a 

1635 different value than that of the :class:`.ExecutionContext`, 

1636 potentially in the case where a 

1637 :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar 

1638 modified the statement/parameters to be sent. 

1639 

1640 May be None. 

1641 

1642 """ 

1643 

1644 is_disconnect = None 

1645 """Represent whether the exception as occurred represents a "disconnect" 

1646 condition. 

1647 

1648 This flag will always be True or False within the scope of the 

1649 :meth:`_events.ConnectionEvents.handle_error` handler. 

1650 

1651 SQLAlchemy will defer to this flag in order to determine whether or not 

1652 the connection should be invalidated subsequently. That is, by 

1653 assigning to this flag, a "disconnect" event which then results in 

1654 a connection and pool invalidation can be invoked or prevented by 

1655 changing this flag. 

1656 

1657 

1658 .. note:: The pool "pre_ping" handler enabled using the 

1659 :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not** 

1660 consult this event before deciding if the "ping" returned false, 

1661 as opposed to receiving an unhandled error. For this use case, the 

1662 :ref:`legacy recipe based on engine_connect() may be used 

1663 <pool_disconnects_pessimistic_custom>`. A future API allow more 

1664 comprehensive customization of the "disconnect" detection mechanism 

1665 across all functions. 

1666 

1667 """ 

1668 

1669 invalidate_pool_on_disconnect = True 

1670 """Represent whether all connections in the pool should be invalidated 

1671 when a "disconnect" condition is in effect. 

1672 

1673 Setting this flag to False within the scope of the 

1674 :meth:`_events.ConnectionEvents.handle_error` 

1675 event will have the effect such 

1676 that the full collection of connections in the pool will not be 

1677 invalidated during a disconnect; only the current connection that is the 

1678 subject of the error will actually be invalidated. 

1679 

1680 The purpose of this flag is for custom disconnect-handling schemes where 

1681 the invalidation of other connections in the pool is to be performed 

1682 based on other conditions, or even on a per-connection basis. 

1683 

1684 .. versionadded:: 1.0.3 

1685 

1686 """ 

1687 

1688 

1689class AdaptedConnection(object): 

1690 """Interface of an adapted connection object to support the DBAPI protocol. 

1691 

1692 Used by asyncio dialects to provide a sync-style pep-249 facade on top 

1693 of the asyncio connection/cursor API provided by the driver. 

1694 

1695 .. versionadded:: 1.4.24 

1696 

1697 """ 

1698 

1699 __slots__ = ("_connection",) 

1700 

1701 @property 

1702 def driver_connection(self): 

1703 """The connection object as returned by the driver after a connect.""" 

1704 return self._connection 

1705 

1706 def run_async(self, fn): 

1707 """Run the awaitable returned by the given function, which is passed 

1708 the raw asyncio driver connection. 

1709 

1710 This is used to invoke awaitable-only methods on the driver connection 

1711 within the context of a "synchronous" method, like a connection 

1712 pool event handler. 

1713 

1714 E.g.:: 

1715 

1716 engine = create_async_engine(...) 

1717 

1718 @event.listens_for(engine.sync_engine, "connect") 

1719 def register_custom_types(dbapi_connection, ...): 

1720 dbapi_connection.run_async( 

1721 lambda connection: connection.set_type_codec( 

1722 'MyCustomType', encoder, decoder, ... 

1723 ) 

1724 ) 

1725 

1726 .. versionadded:: 1.4.30 

1727 

1728 .. seealso:: 

1729 

1730 :ref:`asyncio_events_run_async` 

1731 

1732 """ 

1733 return await_only(fn(self._connection)) 

1734 

1735 def __repr__(self): 

1736 return "<AdaptedConnection %s>" % self._connection