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

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

703 statements  

1# engine/interfaces.py 

2# Copyright (C) 2005-2025 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 __future__ import annotations 

11 

12from enum import Enum 

13from typing import Any 

14from typing import Awaitable 

15from typing import Callable 

16from typing import ClassVar 

17from typing import Collection 

18from typing import Dict 

19from typing import Iterable 

20from typing import Iterator 

21from typing import List 

22from typing import Mapping 

23from typing import MutableMapping 

24from typing import Optional 

25from typing import Sequence 

26from typing import Set 

27from typing import Tuple 

28from typing import Type 

29from typing import TYPE_CHECKING 

30from typing import TypeVar 

31from typing import Union 

32 

33from .. import util 

34from ..event import EventTarget 

35from ..pool import Pool 

36from ..pool import PoolProxiedConnection as PoolProxiedConnection 

37from ..sql.compiler import Compiled as Compiled 

38from ..sql.compiler import Compiled # noqa 

39from ..sql.compiler import TypeCompiler as TypeCompiler 

40from ..sql.compiler import TypeCompiler # noqa 

41from ..util import immutabledict 

42from ..util.concurrency import await_only 

43from ..util.typing import Literal 

44from ..util.typing import NotRequired 

45from ..util.typing import Protocol 

46from ..util.typing import TypedDict 

47 

48if TYPE_CHECKING: 

49 from .base import Connection 

50 from .base import Engine 

51 from .cursor import CursorResult 

52 from .url import URL 

53 from ..connectors.asyncio import AsyncIODBAPIConnection 

54 from ..event import _ListenerFnType 

55 from ..event import dispatcher 

56 from ..exc import StatementError 

57 from ..sql import Executable 

58 from ..sql.compiler import _InsertManyValuesBatch 

59 from ..sql.compiler import DDLCompiler 

60 from ..sql.compiler import IdentifierPreparer 

61 from ..sql.compiler import InsertmanyvaluesSentinelOpts 

62 from ..sql.compiler import Linting 

63 from ..sql.compiler import SQLCompiler 

64 from ..sql.elements import BindParameter 

65 from ..sql.elements import ClauseElement 

66 from ..sql.schema import Column 

67 from ..sql.schema import DefaultGenerator 

68 from ..sql.schema import SchemaItem 

69 from ..sql.schema import Sequence as Sequence_SchemaItem 

70 from ..sql.sqltypes import Integer 

71 from ..sql.type_api import _TypeMemoDict 

72 from ..sql.type_api import TypeEngine 

73 from ..util.langhelpers import generic_fn_descriptor 

74 

75ConnectArgsType = Tuple[Sequence[str], MutableMapping[str, Any]] 

76 

77_T = TypeVar("_T", bound="Any") 

78 

79 

80class CacheStats(Enum): 

81 CACHE_HIT = 0 

82 CACHE_MISS = 1 

83 CACHING_DISABLED = 2 

84 NO_CACHE_KEY = 3 

85 NO_DIALECT_SUPPORT = 4 

86 

87 

88class ExecuteStyle(Enum): 

89 """indicates the :term:`DBAPI` cursor method that will be used to invoke 

90 a statement.""" 

91 

92 EXECUTE = 0 

93 """indicates cursor.execute() will be used""" 

94 

95 EXECUTEMANY = 1 

96 """indicates cursor.executemany() will be used.""" 

97 

98 INSERTMANYVALUES = 2 

99 """indicates cursor.execute() will be used with an INSERT where the 

100 VALUES expression will be expanded to accommodate for multiple 

101 parameter sets 

102 

103 .. seealso:: 

104 

105 :ref:`engine_insertmanyvalues` 

106 

107 """ 

108 

109 

110class DBAPIModule(Protocol): 

111 class Error(Exception): 

112 def __getattr__(self, key: str) -> Any: ... 

113 

114 class OperationalError(Error): 

115 pass 

116 

117 class InterfaceError(Error): 

118 pass 

119 

120 class IntegrityError(Error): 

121 pass 

122 

123 def __getattr__(self, key: str) -> Any: ... 

124 

125 

126class DBAPIConnection(Protocol): 

127 """protocol representing a :pep:`249` database connection. 

128 

129 .. versionadded:: 2.0 

130 

131 .. seealso:: 

132 

133 `Connection Objects <https://www.python.org/dev/peps/pep-0249/#connection-objects>`_ 

134 - in :pep:`249` 

135 

136 """ # noqa: E501 

137 

138 def close(self) -> None: ... 

139 

140 def commit(self) -> None: ... 

141 

142 def cursor(self, *args: Any, **kwargs: Any) -> DBAPICursor: ... 

143 

144 def rollback(self) -> None: ... 

145 

146 def __getattr__(self, key: str) -> Any: ... 

147 

148 def __setattr__(self, key: str, value: Any) -> None: ... 

149 

150 

151class DBAPIType(Protocol): 

152 """protocol representing a :pep:`249` database type. 

153 

154 .. versionadded:: 2.0 

155 

156 .. seealso:: 

157 

158 `Type Objects <https://www.python.org/dev/peps/pep-0249/#type-objects>`_ 

159 - in :pep:`249` 

160 

161 """ # noqa: E501 

162 

163 

164class DBAPICursor(Protocol): 

165 """protocol representing a :pep:`249` database cursor. 

166 

167 .. versionadded:: 2.0 

168 

169 .. seealso:: 

170 

171 `Cursor Objects <https://www.python.org/dev/peps/pep-0249/#cursor-objects>`_ 

172 - in :pep:`249` 

173 

174 """ # noqa: E501 

175 

176 @property 

177 def description( 

178 self, 

179 ) -> _DBAPICursorDescription: 

180 """The description attribute of the Cursor. 

181 

182 .. seealso:: 

183 

184 `cursor.description <https://www.python.org/dev/peps/pep-0249/#description>`_ 

185 - in :pep:`249` 

186 

187 

188 """ # noqa: E501 

189 ... 

190 

191 @property 

192 def rowcount(self) -> int: ... 

193 

194 arraysize: int 

195 

196 lastrowid: int 

197 

198 def close(self) -> None: ... 

199 

200 def execute( 

201 self, 

202 operation: Any, 

203 parameters: Optional[_DBAPISingleExecuteParams] = None, 

204 ) -> Any: ... 

205 

206 def executemany( 

207 self, 

208 operation: Any, 

209 parameters: _DBAPIMultiExecuteParams, 

210 ) -> Any: ... 

211 

212 def fetchone(self) -> Optional[Any]: ... 

213 

214 def fetchmany(self, size: int = ...) -> Sequence[Any]: ... 

215 

216 def fetchall(self) -> Sequence[Any]: ... 

217 

218 def setinputsizes(self, sizes: Sequence[Any]) -> None: ... 

219 

220 def setoutputsize(self, size: Any, column: Any) -> None: ... 

221 

222 def callproc( 

223 self, procname: str, parameters: Sequence[Any] = ... 

224 ) -> Any: ... 

225 

226 def nextset(self) -> Optional[bool]: ... 

227 

228 def __getattr__(self, key: str) -> Any: ... 

229 

230 

231_CoreSingleExecuteParams = Mapping[str, Any] 

232_MutableCoreSingleExecuteParams = MutableMapping[str, Any] 

233_CoreMultiExecuteParams = Sequence[_CoreSingleExecuteParams] 

234_CoreAnyExecuteParams = Union[ 

235 _CoreMultiExecuteParams, _CoreSingleExecuteParams 

236] 

237 

238_DBAPISingleExecuteParams = Union[Sequence[Any], _CoreSingleExecuteParams] 

239 

240_DBAPIMultiExecuteParams = Union[ 

241 Sequence[Sequence[Any]], _CoreMultiExecuteParams 

242] 

243_DBAPIAnyExecuteParams = Union[ 

244 _DBAPIMultiExecuteParams, _DBAPISingleExecuteParams 

245] 

246_DBAPICursorDescription = Sequence[ 

247 Tuple[ 

248 str, 

249 "DBAPIType", 

250 Optional[int], 

251 Optional[int], 

252 Optional[int], 

253 Optional[int], 

254 Optional[bool], 

255 ] 

256] 

257 

258_AnySingleExecuteParams = _DBAPISingleExecuteParams 

259_AnyMultiExecuteParams = _DBAPIMultiExecuteParams 

260_AnyExecuteParams = _DBAPIAnyExecuteParams 

261 

262CompiledCacheType = MutableMapping[Any, "Compiled"] 

263SchemaTranslateMapType = Mapping[Optional[str], Optional[str]] 

264 

265_ImmutableExecuteOptions = immutabledict[str, Any] 

266 

267_ParamStyle = Literal[ 

268 "qmark", "numeric", "named", "format", "pyformat", "numeric_dollar" 

269] 

270 

271_GenericSetInputSizesType = List[Tuple[str, Any, "TypeEngine[Any]"]] 

272 

273IsolationLevel = Literal[ 

274 "SERIALIZABLE", 

275 "REPEATABLE READ", 

276 "READ COMMITTED", 

277 "READ UNCOMMITTED", 

278 "AUTOCOMMIT", 

279] 

280 

281 

282class _CoreKnownExecutionOptions(TypedDict, total=False): 

283 compiled_cache: Optional[CompiledCacheType] 

284 logging_token: str 

285 isolation_level: IsolationLevel 

286 no_parameters: bool 

287 stream_results: bool 

288 max_row_buffer: int 

289 yield_per: int 

290 insertmanyvalues_page_size: int 

291 schema_translate_map: Optional[SchemaTranslateMapType] 

292 preserve_rowcount: bool 

293 

294 

295_ExecuteOptions = immutabledict[str, Any] 

296CoreExecuteOptionsParameter = Union[ 

297 _CoreKnownExecutionOptions, Mapping[str, Any] 

298] 

299 

300 

301class ReflectedIdentity(TypedDict): 

302 """represent the reflected IDENTITY structure of a column, corresponding 

303 to the :class:`_schema.Identity` construct. 

304 

305 The :class:`.ReflectedIdentity` structure is part of the 

306 :class:`.ReflectedColumn` structure, which is returned by the 

307 :meth:`.Inspector.get_columns` method. 

308 

309 """ 

310 

311 always: bool 

312 """type of identity column""" 

313 

314 on_null: bool 

315 """indicates ON NULL""" 

316 

317 start: int 

318 """starting index of the sequence""" 

319 

320 increment: int 

321 """increment value of the sequence""" 

322 

323 minvalue: int 

324 """the minimum value of the sequence.""" 

325 

326 maxvalue: int 

327 """the maximum value of the sequence.""" 

328 

329 nominvalue: bool 

330 """no minimum value of the sequence.""" 

331 

332 nomaxvalue: bool 

333 """no maximum value of the sequence.""" 

334 

335 cycle: bool 

336 """allows the sequence to wrap around when the maxvalue 

337 or minvalue has been reached.""" 

338 

339 cache: Optional[int] 

340 """number of future values in the 

341 sequence which are calculated in advance.""" 

342 

343 order: bool 

344 """if true, renders the ORDER keyword.""" 

345 

346 

347class ReflectedComputed(TypedDict): 

348 """Represent the reflected elements of a computed column, corresponding 

349 to the :class:`_schema.Computed` construct. 

350 

351 The :class:`.ReflectedComputed` structure is part of the 

352 :class:`.ReflectedColumn` structure, which is returned by the 

353 :meth:`.Inspector.get_columns` method. 

354 

355 """ 

356 

357 sqltext: str 

358 """the expression used to generate this column returned 

359 as a string SQL expression""" 

360 

361 persisted: NotRequired[bool] 

362 """indicates if the value is stored in the table or computed on demand""" 

363 

364 

365class ReflectedColumn(TypedDict): 

366 """Dictionary representing the reflected elements corresponding to 

367 a :class:`_schema.Column` object. 

368 

369 The :class:`.ReflectedColumn` structure is returned by the 

370 :class:`.Inspector.get_columns` method. 

371 

372 """ 

373 

374 name: str 

375 """column name""" 

376 

377 type: TypeEngine[Any] 

378 """column type represented as a :class:`.TypeEngine` instance.""" 

379 

380 nullable: bool 

381 """boolean flag if the column is NULL or NOT NULL""" 

382 

383 default: Optional[str] 

384 """column default expression as a SQL string""" 

385 

386 autoincrement: NotRequired[bool] 

387 """database-dependent autoincrement flag. 

388 

389 This flag indicates if the column has a database-side "autoincrement" 

390 flag of some kind. Within SQLAlchemy, other kinds of columns may 

391 also act as an "autoincrement" column without necessarily having 

392 such a flag on them. 

393 

394 See :paramref:`_schema.Column.autoincrement` for more background on 

395 "autoincrement". 

396 

397 """ 

398 

399 comment: NotRequired[Optional[str]] 

400 """comment for the column, if present. 

401 Only some dialects return this key 

402 """ 

403 

404 computed: NotRequired[ReflectedComputed] 

405 """indicates that this column is computed by the database. 

406 Only some dialects return this key. 

407 

408 .. versionadded:: 1.3.16 - added support for computed reflection. 

409 """ 

410 

411 identity: NotRequired[ReflectedIdentity] 

412 """indicates this column is an IDENTITY column. 

413 Only some dialects return this key. 

414 

415 .. versionadded:: 1.4 - added support for identity column reflection. 

416 """ 

417 

418 dialect_options: NotRequired[Dict[str, Any]] 

419 """Additional dialect-specific options detected for this reflected 

420 object""" 

421 

422 

423class ReflectedConstraint(TypedDict): 

424 """Dictionary representing the reflected elements corresponding to 

425 :class:`.Constraint` 

426 

427 A base class for all constraints 

428 """ 

429 

430 name: Optional[str] 

431 """constraint name""" 

432 

433 comment: NotRequired[Optional[str]] 

434 """comment for the constraint, if present""" 

435 

436 

437class ReflectedCheckConstraint(ReflectedConstraint): 

438 """Dictionary representing the reflected elements corresponding to 

439 :class:`.CheckConstraint`. 

440 

441 The :class:`.ReflectedCheckConstraint` structure is returned by the 

442 :meth:`.Inspector.get_check_constraints` method. 

443 

444 """ 

445 

446 sqltext: str 

447 """the check constraint's SQL expression""" 

448 

449 dialect_options: NotRequired[Dict[str, Any]] 

450 """Additional dialect-specific options detected for this check constraint 

451 

452 .. versionadded:: 1.3.8 

453 """ 

454 

455 

456class ReflectedUniqueConstraint(ReflectedConstraint): 

457 """Dictionary representing the reflected elements corresponding to 

458 :class:`.UniqueConstraint`. 

459 

460 The :class:`.ReflectedUniqueConstraint` structure is returned by the 

461 :meth:`.Inspector.get_unique_constraints` method. 

462 

463 """ 

464 

465 column_names: List[str] 

466 """column names which comprise the unique constraint""" 

467 

468 duplicates_index: NotRequired[Optional[str]] 

469 "Indicates if this unique constraint duplicates an index with this name" 

470 

471 dialect_options: NotRequired[Dict[str, Any]] 

472 """Additional dialect-specific options detected for this unique 

473 constraint""" 

474 

475 

476class ReflectedPrimaryKeyConstraint(ReflectedConstraint): 

477 """Dictionary representing the reflected elements corresponding to 

478 :class:`.PrimaryKeyConstraint`. 

479 

480 The :class:`.ReflectedPrimaryKeyConstraint` structure is returned by the 

481 :meth:`.Inspector.get_pk_constraint` method. 

482 

483 """ 

484 

485 constrained_columns: List[str] 

486 """column names which comprise the primary key""" 

487 

488 dialect_options: NotRequired[Dict[str, Any]] 

489 """Additional dialect-specific options detected for this primary key""" 

490 

491 

492class ReflectedForeignKeyConstraint(ReflectedConstraint): 

493 """Dictionary representing the reflected elements corresponding to 

494 :class:`.ForeignKeyConstraint`. 

495 

496 The :class:`.ReflectedForeignKeyConstraint` structure is returned by 

497 the :meth:`.Inspector.get_foreign_keys` method. 

498 

499 """ 

500 

501 constrained_columns: List[str] 

502 """local column names which comprise the foreign key""" 

503 

504 referred_schema: Optional[str] 

505 """schema name of the table being referred""" 

506 

507 referred_table: str 

508 """name of the table being referred""" 

509 

510 referred_columns: List[str] 

511 """referred column names that correspond to ``constrained_columns``""" 

512 

513 options: NotRequired[Dict[str, Any]] 

514 """Additional options detected for this foreign key constraint""" 

515 

516 

517class ReflectedIndex(TypedDict): 

518 """Dictionary representing the reflected elements corresponding to 

519 :class:`.Index`. 

520 

521 The :class:`.ReflectedIndex` structure is returned by the 

522 :meth:`.Inspector.get_indexes` method. 

523 

524 """ 

525 

526 name: Optional[str] 

527 """index name""" 

528 

529 column_names: List[Optional[str]] 

530 """column names which the index references. 

531 An element of this list is ``None`` if it's an expression and is 

532 returned in the ``expressions`` list. 

533 """ 

534 

535 expressions: NotRequired[List[str]] 

536 """Expressions that compose the index. This list, when present, contains 

537 both plain column names (that are also in ``column_names``) and 

538 expressions (that are ``None`` in ``column_names``). 

539 """ 

540 

541 unique: bool 

542 """whether or not the index has a unique flag""" 

543 

544 duplicates_constraint: NotRequired[Optional[str]] 

545 "Indicates if this index mirrors a constraint with this name" 

546 

547 include_columns: NotRequired[List[str]] 

548 """columns to include in the INCLUDE clause for supporting databases. 

549 

550 .. deprecated:: 2.0 

551 

552 Legacy value, will be replaced with 

553 ``index_dict["dialect_options"]["<dialect name>_include"]`` 

554 

555 """ 

556 

557 column_sorting: NotRequired[Dict[str, Tuple[str]]] 

558 """optional dict mapping column names or expressions to tuple of sort 

559 keywords, which may include ``asc``, ``desc``, ``nulls_first``, 

560 ``nulls_last``. 

561 

562 .. versionadded:: 1.3.5 

563 """ 

564 

565 dialect_options: NotRequired[Dict[str, Any]] 

566 """Additional dialect-specific options detected for this index""" 

567 

568 

569class ReflectedTableComment(TypedDict): 

570 """Dictionary representing the reflected comment corresponding to 

571 the :attr:`_schema.Table.comment` attribute. 

572 

573 The :class:`.ReflectedTableComment` structure is returned by the 

574 :meth:`.Inspector.get_table_comment` method. 

575 

576 """ 

577 

578 text: Optional[str] 

579 """text of the comment""" 

580 

581 

582class BindTyping(Enum): 

583 """Define different methods of passing typing information for 

584 bound parameters in a statement to the database driver. 

585 

586 .. versionadded:: 2.0 

587 

588 """ 

589 

590 NONE = 1 

591 """No steps are taken to pass typing information to the database driver. 

592 

593 This is the default behavior for databases such as SQLite, MySQL / MariaDB, 

594 SQL Server. 

595 

596 """ 

597 

598 SETINPUTSIZES = 2 

599 """Use the pep-249 setinputsizes method. 

600 

601 This is only implemented for DBAPIs that support this method and for which 

602 the SQLAlchemy dialect has the appropriate infrastructure for that dialect 

603 set up. Current dialects include python-oracledb, cx_Oracle as well as 

604 optional support for SQL Server using pyodbc. 

605 

606 When using setinputsizes, dialects also have a means of only using the 

607 method for certain datatypes using include/exclude lists. 

608 

609 When SETINPUTSIZES is used, the :meth:`.Dialect.do_set_input_sizes` method 

610 is called for each statement executed which has bound parameters. 

611 

612 """ 

613 

614 RENDER_CASTS = 3 

615 """Render casts or other directives in the SQL string. 

616 

617 This method is used for all PostgreSQL dialects, including asyncpg, 

618 pg8000, psycopg, psycopg2. Dialects which implement this can choose 

619 which kinds of datatypes are explicitly cast in SQL statements and which 

620 aren't. 

621 

622 When RENDER_CASTS is used, the compiler will invoke the 

623 :meth:`.SQLCompiler.render_bind_cast` method for the rendered 

624 string representation of each :class:`.BindParameter` object whose 

625 dialect-level type sets the :attr:`.TypeEngine.render_bind_cast` attribute. 

626 

627 The :meth:`.SQLCompiler.render_bind_cast` is also used to render casts 

628 for one form of "insertmanyvalues" query, when both 

629 :attr:`.InsertmanyvaluesSentinelOpts.USE_INSERT_FROM_SELECT` and 

630 :attr:`.InsertmanyvaluesSentinelOpts.RENDER_SELECT_COL_CASTS` are set, 

631 where the casts are applied to the intermediary columns e.g. 

632 "INSERT INTO t (a, b, c) SELECT p0::TYP, p1::TYP, p2::TYP " 

633 "FROM (VALUES (?, ?), (?, ?), ...)". 

634 

635 .. versionadded:: 2.0.10 - :meth:`.SQLCompiler.render_bind_cast` is now 

636 used within some elements of the "insertmanyvalues" implementation. 

637 

638 

639 """ 

640 

641 

642VersionInfoType = Tuple[Union[int, str], ...] 

643TableKey = Tuple[Optional[str], str] 

644 

645 

646class Dialect(EventTarget): 

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

648 

649 Any aspect of metadata definition, SQL query generation, 

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

651 between databases is defined under the general category of the 

652 Dialect. The Dialect acts as a factory for other 

653 database-specific object implementations including 

654 ExecutionContext, Compiled, DefaultGenerator, and TypeEngine. 

655 

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

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

658 descendant class. 

659 

660 """ 

661 

662 CACHE_HIT = CacheStats.CACHE_HIT 

663 CACHE_MISS = CacheStats.CACHE_MISS 

664 CACHING_DISABLED = CacheStats.CACHING_DISABLED 

665 NO_CACHE_KEY = CacheStats.NO_CACHE_KEY 

666 NO_DIALECT_SUPPORT = CacheStats.NO_DIALECT_SUPPORT 

667 

668 dispatch: dispatcher[Dialect] 

669 

670 name: str 

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

672 (i.e. 'sqlite') 

673 """ 

674 

675 driver: str 

676 """identifying name for the dialect's DBAPI""" 

677 

678 dialect_description: str 

679 

680 dbapi: Optional[DBAPIModule] 

681 """A reference to the DBAPI module object itself. 

682 

683 SQLAlchemy dialects import DBAPI modules using the classmethod 

684 :meth:`.Dialect.import_dbapi`. The rationale is so that any dialect 

685 module can be imported and used to generate SQL statements without the 

686 need for the actual DBAPI driver to be installed. Only when an 

687 :class:`.Engine` is constructed using :func:`.create_engine` does the 

688 DBAPI get imported; at that point, the creation process will assign 

689 the DBAPI module to this attribute. 

690 

691 Dialects should therefore implement :meth:`.Dialect.import_dbapi` 

692 which will import the necessary module and return it, and then refer 

693 to ``self.dbapi`` in dialect code in order to refer to the DBAPI module 

694 contents. 

695 

696 .. versionchanged:: The :attr:`.Dialect.dbapi` attribute is exclusively 

697 used as the per-:class:`.Dialect`-instance reference to the DBAPI 

698 module. The previous not-fully-documented ``.Dialect.dbapi()`` 

699 classmethod is deprecated and replaced by :meth:`.Dialect.import_dbapi`. 

700 

701 """ 

702 

703 @util.non_memoized_property 

704 def loaded_dbapi(self) -> DBAPIModule: 

705 """same as .dbapi, but is never None; will raise an error if no 

706 DBAPI was set up. 

707 

708 .. versionadded:: 2.0 

709 

710 """ 

711 raise NotImplementedError() 

712 

713 positional: bool 

714 """True if the paramstyle for this Dialect is positional.""" 

715 

716 paramstyle: str 

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

718 paramstyles). 

719 """ 

720 

721 compiler_linting: Linting 

722 

723 statement_compiler: Type[SQLCompiler] 

724 """a :class:`.Compiled` class used to compile SQL statements""" 

725 

726 ddl_compiler: Type[DDLCompiler] 

727 """a :class:`.Compiled` class used to compile DDL statements""" 

728 

729 type_compiler_cls: ClassVar[Type[TypeCompiler]] 

730 """a :class:`.Compiled` class used to compile SQL type objects 

731 

732 .. versionadded:: 2.0 

733 

734 """ 

735 

736 type_compiler_instance: TypeCompiler 

737 """instance of a :class:`.Compiled` class used to compile SQL type 

738 objects 

739 

740 .. versionadded:: 2.0 

741 

742 """ 

743 

744 type_compiler: Any 

745 """legacy; this is a TypeCompiler class at the class level, a 

746 TypeCompiler instance at the instance level. 

747 

748 Refer to type_compiler_instance instead. 

749 

750 """ 

751 

752 preparer: Type[IdentifierPreparer] 

753 """a :class:`.IdentifierPreparer` class used to 

754 quote identifiers. 

755 """ 

756 

757 identifier_preparer: IdentifierPreparer 

758 """This element will refer to an instance of :class:`.IdentifierPreparer` 

759 once a :class:`.DefaultDialect` has been constructed. 

760 

761 """ 

762 

763 server_version_info: Optional[Tuple[Any, ...]] 

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

765 

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

767 typically populated during the initial connection to the database. 

768 """ 

769 

770 default_schema_name: Optional[str] 

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

772 supporting dialects, and is typically populated during the 

773 initial connection to the database. 

774 

775 """ 

776 

777 # NOTE: this does not take into effect engine-level isolation level. 

778 # not clear if this should be changed, seems like it should 

779 default_isolation_level: Optional[IsolationLevel] 

780 """the isolation that is implicitly present on new connections""" 

781 

782 skip_autocommit_rollback: bool 

783 """Whether or not the :paramref:`.create_engine.skip_autocommit_rollback` 

784 parameter was set. 

785 

786 .. versionadded:: 2.0.43 

787 

788 """ 

789 

790 # create_engine() -> isolation_level currently goes here 

791 _on_connect_isolation_level: Optional[IsolationLevel] 

792 

793 execution_ctx_cls: Type[ExecutionContext] 

794 """a :class:`.ExecutionContext` class used to handle statement execution""" 

795 

796 execute_sequence_format: Union[ 

797 Type[Tuple[Any, ...]], Type[Tuple[List[Any]]] 

798 ] 

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

800 accepts for the second argument (they vary).""" 

801 

802 supports_alter: bool 

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

804 generating foreign key constraints in certain circumstances 

805 """ 

806 

807 max_identifier_length: int 

808 """The maximum length of identifier names.""" 

809 max_index_name_length: Optional[int] 

810 """The maximum length of index names if different from 

811 ``max_identifier_length``.""" 

812 max_constraint_name_length: Optional[int] 

813 """The maximum length of constraint names if different from 

814 ``max_identifier_length``.""" 

815 

816 supports_server_side_cursors: Union[generic_fn_descriptor[bool], bool] 

817 """indicates if the dialect supports server side cursors""" 

818 

819 server_side_cursors: bool 

820 """deprecated; indicates if the dialect should attempt to use server 

821 side cursors by default""" 

822 

823 supports_sane_rowcount: bool 

824 """Indicate whether the dialect properly implements rowcount for 

825 ``UPDATE`` and ``DELETE`` statements. 

826 """ 

827 

828 supports_sane_multi_rowcount: bool 

829 """Indicate whether the dialect properly implements rowcount for 

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

831 executemany. 

832 """ 

833 

834 supports_empty_insert: bool 

835 """dialect supports INSERT () VALUES (), i.e. a plain INSERT with no 

836 columns in it. 

837 

838 This is not usually supported; an "empty" insert is typically 

839 suited using either "INSERT..DEFAULT VALUES" or 

840 "INSERT ... (col) VALUES (DEFAULT)". 

841 

842 """ 

843 

844 supports_default_values: bool 

845 """dialect supports INSERT... DEFAULT VALUES syntax""" 

846 

847 supports_default_metavalue: bool 

848 """dialect supports INSERT...(col) VALUES (DEFAULT) syntax. 

849 

850 Most databases support this in some way, e.g. SQLite supports it using 

851 ``VALUES (NULL)``. MS SQL Server supports the syntax also however 

852 is the only included dialect where we have this disabled, as 

853 MSSQL does not support the field for the IDENTITY column, which is 

854 usually where we like to make use of the feature. 

855 

856 """ 

857 

858 default_metavalue_token: str = "DEFAULT" 

859 """for INSERT... VALUES (DEFAULT) syntax, the token to put in the 

860 parenthesis. 

861 

862 E.g. for SQLite this is the keyword "NULL". 

863 

864 """ 

865 

866 supports_multivalues_insert: bool 

867 """Target database supports INSERT...VALUES with multiple value 

868 sets, i.e. INSERT INTO table (cols) VALUES (...), (...), (...), ... 

869 

870 """ 

871 

872 insert_executemany_returning: bool 

873 """dialect / driver / database supports some means of providing 

874 INSERT...RETURNING support when dialect.do_executemany() is used. 

875 

876 """ 

877 

878 insert_executemany_returning_sort_by_parameter_order: bool 

879 """dialect / driver / database supports some means of providing 

880 INSERT...RETURNING support when dialect.do_executemany() is used 

881 along with the :paramref:`_dml.Insert.returning.sort_by_parameter_order` 

882 parameter being set. 

883 

884 """ 

885 

886 update_executemany_returning: bool 

887 """dialect supports UPDATE..RETURNING with executemany.""" 

888 

889 delete_executemany_returning: bool 

890 """dialect supports DELETE..RETURNING with executemany.""" 

891 

892 use_insertmanyvalues: bool 

893 """if True, indicates "insertmanyvalues" functionality should be used 

894 to allow for ``insert_executemany_returning`` behavior, if possible. 

895 

896 In practice, setting this to True means: 

897 

898 if ``supports_multivalues_insert``, ``insert_returning`` and 

899 ``use_insertmanyvalues`` are all True, the SQL compiler will produce 

900 an INSERT that will be interpreted by the :class:`.DefaultDialect` 

901 as an :attr:`.ExecuteStyle.INSERTMANYVALUES` execution that allows 

902 for INSERT of many rows with RETURNING by rewriting a single-row 

903 INSERT statement to have multiple VALUES clauses, also executing 

904 the statement multiple times for a series of batches when large numbers 

905 of rows are given. 

906 

907 The parameter is False for the default dialect, and is set to True for 

908 SQLAlchemy internal dialects SQLite, MySQL/MariaDB, PostgreSQL, SQL Server. 

909 It remains at False for Oracle Database, which provides native "executemany 

910 with RETURNING" support and also does not support 

911 ``supports_multivalues_insert``. For MySQL/MariaDB, those MySQL dialects 

912 that don't support RETURNING will not report 

913 ``insert_executemany_returning`` as True. 

914 

915 .. versionadded:: 2.0 

916 

917 .. seealso:: 

918 

919 :ref:`engine_insertmanyvalues` 

920 

921 """ 

922 

923 use_insertmanyvalues_wo_returning: bool 

924 """if True, and use_insertmanyvalues is also True, INSERT statements 

925 that don't include RETURNING will also use "insertmanyvalues". 

926 

927 .. versionadded:: 2.0 

928 

929 .. seealso:: 

930 

931 :ref:`engine_insertmanyvalues` 

932 

933 """ 

934 

935 insertmanyvalues_implicit_sentinel: InsertmanyvaluesSentinelOpts 

936 """Options indicating the database supports a form of bulk INSERT where 

937 the autoincrement integer primary key can be reliably used as an ordering 

938 for INSERTed rows. 

939 

940 .. versionadded:: 2.0.10 

941 

942 .. seealso:: 

943 

944 :ref:`engine_insertmanyvalues_returning_order` 

945 

946 """ 

947 

948 insertmanyvalues_page_size: int 

949 """Number of rows to render into an individual INSERT..VALUES() statement 

950 for :attr:`.ExecuteStyle.INSERTMANYVALUES` executions. 

951 

952 The default dialect defaults this to 1000. 

953 

954 .. versionadded:: 2.0 

955 

956 .. seealso:: 

957 

958 :paramref:`_engine.Connection.execution_options.insertmanyvalues_page_size` - 

959 execution option available on :class:`_engine.Connection`, statements 

960 

961 """ # noqa: E501 

962 

963 insertmanyvalues_max_parameters: int 

964 """Alternate to insertmanyvalues_page_size, will additionally limit 

965 page size based on number of parameters total in the statement. 

966 

967 

968 """ 

969 

970 preexecute_autoincrement_sequences: bool 

971 """True if 'implicit' primary key functions must be executed separately 

972 in order to get their value, if RETURNING is not used. 

973 

974 This is currently oriented towards PostgreSQL when the 

975 ``implicit_returning=False`` parameter is used on a :class:`.Table` 

976 object. 

977 

978 """ 

979 

980 insert_returning: bool 

981 """if the dialect supports RETURNING with INSERT 

982 

983 .. versionadded:: 2.0 

984 

985 """ 

986 

987 update_returning: bool 

988 """if the dialect supports RETURNING with UPDATE 

989 

990 .. versionadded:: 2.0 

991 

992 """ 

993 

994 update_returning_multifrom: bool 

995 """if the dialect supports RETURNING with UPDATE..FROM 

996 

997 .. versionadded:: 2.0 

998 

999 """ 

1000 

1001 delete_returning: bool 

1002 """if the dialect supports RETURNING with DELETE 

1003 

1004 .. versionadded:: 2.0 

1005 

1006 """ 

1007 

1008 delete_returning_multifrom: bool 

1009 """if the dialect supports RETURNING with DELETE..FROM 

1010 

1011 .. versionadded:: 2.0 

1012 

1013 """ 

1014 

1015 favor_returning_over_lastrowid: bool 

1016 """for backends that support both a lastrowid and a RETURNING insert 

1017 strategy, favor RETURNING for simple single-int pk inserts. 

1018 

1019 cursor.lastrowid tends to be more performant on most backends. 

1020 

1021 """ 

1022 

1023 supports_identity_columns: bool 

1024 """target database supports IDENTITY""" 

1025 

1026 cte_follows_insert: bool 

1027 """target database, when given a CTE with an INSERT statement, needs 

1028 the CTE to be below the INSERT""" 

1029 

1030 colspecs: MutableMapping[Type[TypeEngine[Any]], Type[TypeEngine[Any]]] 

1031 """A dictionary of TypeEngine classes from sqlalchemy.types mapped 

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

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

1034 dialect instance itself. 

1035 """ 

1036 

1037 supports_sequences: bool 

1038 """Indicates if the dialect supports CREATE SEQUENCE or similar.""" 

1039 

1040 sequences_optional: bool 

1041 """If True, indicates if the :paramref:`_schema.Sequence.optional` 

1042 parameter on the :class:`_schema.Sequence` construct 

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

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

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

1046 other backends. 

1047 """ 

1048 

1049 default_sequence_base: int 

1050 """the default value that will be rendered as the "START WITH" portion of 

1051 a CREATE SEQUENCE DDL statement. 

1052 

1053 """ 

1054 

1055 supports_native_enum: bool 

1056 """Indicates if the dialect supports a native ENUM construct. 

1057 This will prevent :class:`_types.Enum` from generating a CHECK 

1058 constraint when that type is used in "native" mode. 

1059 """ 

1060 

1061 supports_native_boolean: bool 

1062 """Indicates if the dialect supports a native boolean construct. 

1063 This will prevent :class:`_types.Boolean` from generating a CHECK 

1064 constraint when that type is used. 

1065 """ 

1066 

1067 supports_native_decimal: bool 

1068 """indicates if Decimal objects are handled and returned for precision 

1069 numeric types, or if floats are returned""" 

1070 

1071 supports_native_uuid: bool 

1072 """indicates if Python UUID() objects are handled natively by the 

1073 driver for SQL UUID datatypes. 

1074 

1075 .. versionadded:: 2.0 

1076 

1077 """ 

1078 

1079 returns_native_bytes: bool 

1080 """indicates if Python bytes() objects are returned natively by the 

1081 driver for SQL "binary" datatypes. 

1082 

1083 .. versionadded:: 2.0.11 

1084 

1085 """ 

1086 

1087 construct_arguments: Optional[ 

1088 List[Tuple[Type[Union[SchemaItem, ClauseElement]], Mapping[str, Any]]] 

1089 ] = None 

1090 """Optional set of argument specifiers for various SQLAlchemy 

1091 constructs, typically schema items. 

1092 

1093 To implement, establish as a series of tuples, as in:: 

1094 

1095 construct_arguments = [ 

1096 (schema.Index, {"using": False, "where": None, "ops": None}), 

1097 ] 

1098 

1099 If the above construct is established on the PostgreSQL dialect, 

1100 the :class:`.Index` construct will now accept the keyword arguments 

1101 ``postgresql_using``, ``postgresql_where``, nad ``postgresql_ops``. 

1102 Any other argument specified to the constructor of :class:`.Index` 

1103 which is prefixed with ``postgresql_`` will raise :class:`.ArgumentError`. 

1104 

1105 A dialect which does not include a ``construct_arguments`` member will 

1106 not participate in the argument validation system. For such a dialect, 

1107 any argument name is accepted by all participating constructs, within 

1108 the namespace of arguments prefixed with that dialect name. The rationale 

1109 here is so that third-party dialects that haven't yet implemented this 

1110 feature continue to function in the old way. 

1111 

1112 .. seealso:: 

1113 

1114 :class:`.DialectKWArgs` - implementing base class which consumes 

1115 :attr:`.DefaultDialect.construct_arguments` 

1116 

1117 

1118 """ 

1119 

1120 reflection_options: Sequence[str] = () 

1121 """Sequence of string names indicating keyword arguments that can be 

1122 established on a :class:`.Table` object which will be passed as 

1123 "reflection options" when using :paramref:`.Table.autoload_with`. 

1124 

1125 Current example is "oracle_resolve_synonyms" in the Oracle Database 

1126 dialects. 

1127 

1128 """ 

1129 

1130 dbapi_exception_translation_map: Mapping[str, str] = util.EMPTY_DICT 

1131 """A dictionary of names that will contain as values the names of 

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

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

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

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

1136 majority of cases this dictionary is empty. 

1137 """ 

1138 

1139 supports_comments: bool 

1140 """Indicates the dialect supports comment DDL on tables and columns.""" 

1141 

1142 inline_comments: bool 

1143 """Indicates the dialect supports comment DDL that's inline with the 

1144 definition of a Table or Column. If False, this implies that ALTER must 

1145 be used to set table and column comments.""" 

1146 

1147 supports_constraint_comments: bool 

1148 """Indicates if the dialect supports comment DDL on constraints. 

1149 

1150 .. versionadded:: 2.0 

1151 """ 

1152 

1153 _has_events = False 

1154 

1155 supports_statement_cache: bool = True 

1156 """indicates if this dialect supports caching. 

1157 

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

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

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

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

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

1163 compliant with SQL statement caching. 

1164 

1165 .. versionadded:: 1.4.5 

1166 

1167 .. seealso:: 

1168 

1169 :ref:`engine_thirdparty_caching` 

1170 

1171 """ 

1172 

1173 _supports_statement_cache: bool 

1174 """internal evaluation for supports_statement_cache""" 

1175 

1176 bind_typing = BindTyping.NONE 

1177 """define a means of passing typing information to the database and/or 

1178 driver for bound parameters. 

1179 

1180 See :class:`.BindTyping` for values. 

1181 

1182 .. versionadded:: 2.0 

1183 

1184 """ 

1185 

1186 is_async: bool 

1187 """Whether or not this dialect is intended for asyncio use.""" 

1188 

1189 has_terminate: bool 

1190 """Whether or not this dialect has a separate "terminate" implementation 

1191 that does not block or require awaiting.""" 

1192 

1193 engine_config_types: Mapping[str, Any] 

1194 """a mapping of string keys that can be in an engine config linked to 

1195 type conversion functions. 

1196 

1197 """ 

1198 

1199 label_length: Optional[int] 

1200 """optional user-defined max length for SQL labels""" 

1201 

1202 include_set_input_sizes: Optional[Set[Any]] 

1203 """set of DBAPI type objects that should be included in 

1204 automatic cursor.setinputsizes() calls. 

1205 

1206 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 

1207 

1208 """ 

1209 

1210 exclude_set_input_sizes: Optional[Set[Any]] 

1211 """set of DBAPI type objects that should be excluded in 

1212 automatic cursor.setinputsizes() calls. 

1213 

1214 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 

1215 

1216 """ 

1217 

1218 supports_simple_order_by_label: bool 

1219 """target database supports ORDER BY <labelname>, where <labelname> 

1220 refers to a label in the columns clause of the SELECT""" 

1221 

1222 div_is_floordiv: bool 

1223 """target database treats the / division operator as "floor division" """ 

1224 

1225 tuple_in_values: bool 

1226 """target database supports tuple IN, i.e. (x, y) IN ((q, p), (r, z))""" 

1227 

1228 _bind_typing_render_casts: bool 

1229 

1230 _type_memos: MutableMapping[TypeEngine[Any], _TypeMemoDict] 

1231 

1232 def _builtin_onconnect(self) -> Optional[_ListenerFnType]: 

1233 raise NotImplementedError() 

1234 

1235 def create_connect_args(self, url: URL) -> ConnectArgsType: 

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

1237 

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

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

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

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

1242 ``connect()`` function. 

1243 

1244 The method typically makes use of the 

1245 :meth:`.URL.translate_connect_args` 

1246 method in order to generate a dictionary of options. 

1247 

1248 The default implementation is:: 

1249 

1250 def create_connect_args(self, url): 

1251 opts = url.translate_connect_args() 

1252 opts.update(url.query) 

1253 return ([], opts) 

1254 

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

1256 

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

1258 :meth:`.Dialect.connect` method. 

1259 

1260 .. seealso:: 

1261 

1262 :meth:`.URL.translate_connect_args` 

1263 

1264 """ 

1265 

1266 raise NotImplementedError() 

1267 

1268 @classmethod 

1269 def import_dbapi(cls) -> DBAPIModule: 

1270 """Import the DBAPI module that is used by this dialect. 

1271 

1272 The Python module object returned here will be assigned as an 

1273 instance variable to a constructed dialect under the name 

1274 ``.dbapi``. 

1275 

1276 .. versionchanged:: 2.0 The :meth:`.Dialect.import_dbapi` class 

1277 method is renamed from the previous method ``.Dialect.dbapi()``, 

1278 which would be replaced at dialect instantiation time by the 

1279 DBAPI module itself, thus using the same name in two different ways. 

1280 If a ``.Dialect.dbapi()`` classmethod is present on a third-party 

1281 dialect, it will be used and a deprecation warning will be emitted. 

1282 

1283 """ 

1284 raise NotImplementedError() 

1285 

1286 def type_descriptor(self, typeobj: TypeEngine[_T]) -> TypeEngine[_T]: 

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

1288 

1289 Dialect classes will usually use the 

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

1291 accomplish this. 

1292 

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

1294 contain no dialect-instance state. 

1295 

1296 """ 

1297 

1298 raise NotImplementedError() 

1299 

1300 def initialize(self, connection: Connection) -> None: 

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

1302 connection. 

1303 

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

1305 other properties. 

1306 

1307 The connection passed here is a SQLAlchemy Connection object, 

1308 with full capabilities. 

1309 

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

1311 super(). 

1312 

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

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

1315 

1316 """ 

1317 

1318 if TYPE_CHECKING: 

1319 

1320 def _overrides_default(self, method_name: str) -> bool: ... 

1321 

1322 def get_columns( 

1323 self, 

1324 connection: Connection, 

1325 table_name: str, 

1326 schema: Optional[str] = None, 

1327 **kw: Any, 

1328 ) -> List[ReflectedColumn]: 

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

1330 

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

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

1333 information as a list of dictionaries 

1334 corresponding to the :class:`.ReflectedColumn` dictionary. 

1335 

1336 This is an internal dialect method. Applications should use 

1337 :meth:`.Inspector.get_columns`. 

1338 

1339 """ 

1340 

1341 raise NotImplementedError() 

1342 

1343 def get_multi_columns( 

1344 self, 

1345 connection: Connection, 

1346 *, 

1347 schema: Optional[str] = None, 

1348 filter_names: Optional[Collection[str]] = None, 

1349 **kw: Any, 

1350 ) -> Iterable[Tuple[TableKey, List[ReflectedColumn]]]: 

1351 """Return information about columns in all tables in the 

1352 given ``schema``. 

1353 

1354 This is an internal dialect method. Applications should use 

1355 :meth:`.Inspector.get_multi_columns`. 

1356 

1357 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1358 implementation that will call the single table method for 

1359 each object returned by :meth:`Dialect.get_table_names`, 

1360 :meth:`Dialect.get_view_names` or 

1361 :meth:`Dialect.get_materialized_view_names` depending on the 

1362 provided ``kind``. Dialects that want to support a faster 

1363 implementation should implement this method. 

1364 

1365 .. versionadded:: 2.0 

1366 

1367 """ 

1368 

1369 raise NotImplementedError() 

1370 

1371 def get_pk_constraint( 

1372 self, 

1373 connection: Connection, 

1374 table_name: str, 

1375 schema: Optional[str] = None, 

1376 **kw: Any, 

1377 ) -> ReflectedPrimaryKeyConstraint: 

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

1379 table_name`. 

1380 

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

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

1383 key information as a dictionary corresponding to the 

1384 :class:`.ReflectedPrimaryKeyConstraint` dictionary. 

1385 

1386 This is an internal dialect method. Applications should use 

1387 :meth:`.Inspector.get_pk_constraint`. 

1388 

1389 """ 

1390 raise NotImplementedError() 

1391 

1392 def get_multi_pk_constraint( 

1393 self, 

1394 connection: Connection, 

1395 *, 

1396 schema: Optional[str] = None, 

1397 filter_names: Optional[Collection[str]] = None, 

1398 **kw: Any, 

1399 ) -> Iterable[Tuple[TableKey, ReflectedPrimaryKeyConstraint]]: 

1400 """Return information about primary key constraints in 

1401 all tables in the given ``schema``. 

1402 

1403 This is an internal dialect method. Applications should use 

1404 :meth:`.Inspector.get_multi_pk_constraint`. 

1405 

1406 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1407 implementation that will call the single table method for 

1408 each object returned by :meth:`Dialect.get_table_names`, 

1409 :meth:`Dialect.get_view_names` or 

1410 :meth:`Dialect.get_materialized_view_names` depending on the 

1411 provided ``kind``. Dialects that want to support a faster 

1412 implementation should implement this method. 

1413 

1414 .. versionadded:: 2.0 

1415 

1416 """ 

1417 raise NotImplementedError() 

1418 

1419 def get_foreign_keys( 

1420 self, 

1421 connection: Connection, 

1422 table_name: str, 

1423 schema: Optional[str] = None, 

1424 **kw: Any, 

1425 ) -> List[ReflectedForeignKeyConstraint]: 

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

1427 

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

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

1430 key information as a list of dicts corresponding to the 

1431 :class:`.ReflectedForeignKeyConstraint` dictionary. 

1432 

1433 This is an internal dialect method. Applications should use 

1434 :meth:`_engine.Inspector.get_foreign_keys`. 

1435 """ 

1436 

1437 raise NotImplementedError() 

1438 

1439 def get_multi_foreign_keys( 

1440 self, 

1441 connection: Connection, 

1442 *, 

1443 schema: Optional[str] = None, 

1444 filter_names: Optional[Collection[str]] = None, 

1445 **kw: Any, 

1446 ) -> Iterable[Tuple[TableKey, List[ReflectedForeignKeyConstraint]]]: 

1447 """Return information about foreign_keys in all tables 

1448 in the given ``schema``. 

1449 

1450 This is an internal dialect method. Applications should use 

1451 :meth:`_engine.Inspector.get_multi_foreign_keys`. 

1452 

1453 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1454 implementation that will call the single table method for 

1455 each object returned by :meth:`Dialect.get_table_names`, 

1456 :meth:`Dialect.get_view_names` or 

1457 :meth:`Dialect.get_materialized_view_names` depending on the 

1458 provided ``kind``. Dialects that want to support a faster 

1459 implementation should implement this method. 

1460 

1461 .. versionadded:: 2.0 

1462 

1463 """ 

1464 

1465 raise NotImplementedError() 

1466 

1467 def get_table_names( 

1468 self, connection: Connection, schema: Optional[str] = None, **kw: Any 

1469 ) -> List[str]: 

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

1471 

1472 This is an internal dialect method. Applications should use 

1473 :meth:`_engine.Inspector.get_table_names`. 

1474 

1475 """ 

1476 

1477 raise NotImplementedError() 

1478 

1479 def get_temp_table_names( 

1480 self, connection: Connection, schema: Optional[str] = None, **kw: Any 

1481 ) -> List[str]: 

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

1483 if supported by the underlying backend. 

1484 

1485 This is an internal dialect method. Applications should use 

1486 :meth:`_engine.Inspector.get_temp_table_names`. 

1487 

1488 """ 

1489 

1490 raise NotImplementedError() 

1491 

1492 def get_view_names( 

1493 self, connection: Connection, schema: Optional[str] = None, **kw: Any 

1494 ) -> List[str]: 

1495 """Return a list of all non-materialized view names available in the 

1496 database. 

1497 

1498 This is an internal dialect method. Applications should use 

1499 :meth:`_engine.Inspector.get_view_names`. 

1500 

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

1502 

1503 """ 

1504 

1505 raise NotImplementedError() 

1506 

1507 def get_materialized_view_names( 

1508 self, connection: Connection, schema: Optional[str] = None, **kw: Any 

1509 ) -> List[str]: 

1510 """Return a list of all materialized view names available in the 

1511 database. 

1512 

1513 This is an internal dialect method. Applications should use 

1514 :meth:`_engine.Inspector.get_materialized_view_names`. 

1515 

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

1517 

1518 .. versionadded:: 2.0 

1519 

1520 """ 

1521 

1522 raise NotImplementedError() 

1523 

1524 def get_sequence_names( 

1525 self, connection: Connection, schema: Optional[str] = None, **kw: Any 

1526 ) -> List[str]: 

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

1528 

1529 This is an internal dialect method. Applications should use 

1530 :meth:`_engine.Inspector.get_sequence_names`. 

1531 

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

1533 

1534 .. versionadded:: 1.4 

1535 """ 

1536 

1537 raise NotImplementedError() 

1538 

1539 def get_temp_view_names( 

1540 self, connection: Connection, schema: Optional[str] = None, **kw: Any 

1541 ) -> List[str]: 

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

1543 if supported by the underlying backend. 

1544 

1545 This is an internal dialect method. Applications should use 

1546 :meth:`_engine.Inspector.get_temp_view_names`. 

1547 

1548 """ 

1549 

1550 raise NotImplementedError() 

1551 

1552 def get_schema_names(self, connection: Connection, **kw: Any) -> List[str]: 

1553 """Return a list of all schema names available in the database. 

1554 

1555 This is an internal dialect method. Applications should use 

1556 :meth:`_engine.Inspector.get_schema_names`. 

1557 """ 

1558 raise NotImplementedError() 

1559 

1560 def get_view_definition( 

1561 self, 

1562 connection: Connection, 

1563 view_name: str, 

1564 schema: Optional[str] = None, 

1565 **kw: Any, 

1566 ) -> str: 

1567 """Return plain or materialized view definition. 

1568 

1569 This is an internal dialect method. Applications should use 

1570 :meth:`_engine.Inspector.get_view_definition`. 

1571 

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

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

1574 definition. 

1575 """ 

1576 

1577 raise NotImplementedError() 

1578 

1579 def get_indexes( 

1580 self, 

1581 connection: Connection, 

1582 table_name: str, 

1583 schema: Optional[str] = None, 

1584 **kw: Any, 

1585 ) -> List[ReflectedIndex]: 

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

1587 

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

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

1590 information as a list of dictionaries corresponding to the 

1591 :class:`.ReflectedIndex` dictionary. 

1592 

1593 This is an internal dialect method. Applications should use 

1594 :meth:`.Inspector.get_indexes`. 

1595 """ 

1596 

1597 raise NotImplementedError() 

1598 

1599 def get_multi_indexes( 

1600 self, 

1601 connection: Connection, 

1602 *, 

1603 schema: Optional[str] = None, 

1604 filter_names: Optional[Collection[str]] = None, 

1605 **kw: Any, 

1606 ) -> Iterable[Tuple[TableKey, List[ReflectedIndex]]]: 

1607 """Return information about indexes in in all tables 

1608 in the given ``schema``. 

1609 

1610 This is an internal dialect method. Applications should use 

1611 :meth:`.Inspector.get_multi_indexes`. 

1612 

1613 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1614 implementation that will call the single table method for 

1615 each object returned by :meth:`Dialect.get_table_names`, 

1616 :meth:`Dialect.get_view_names` or 

1617 :meth:`Dialect.get_materialized_view_names` depending on the 

1618 provided ``kind``. Dialects that want to support a faster 

1619 implementation should implement this method. 

1620 

1621 .. versionadded:: 2.0 

1622 

1623 """ 

1624 

1625 raise NotImplementedError() 

1626 

1627 def get_unique_constraints( 

1628 self, 

1629 connection: Connection, 

1630 table_name: str, 

1631 schema: Optional[str] = None, 

1632 **kw: Any, 

1633 ) -> List[ReflectedUniqueConstraint]: 

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

1635 

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

1637 unique constraint information as a list of dicts corresponding 

1638 to the :class:`.ReflectedUniqueConstraint` dictionary. 

1639 

1640 This is an internal dialect method. Applications should use 

1641 :meth:`.Inspector.get_unique_constraints`. 

1642 """ 

1643 

1644 raise NotImplementedError() 

1645 

1646 def get_multi_unique_constraints( 

1647 self, 

1648 connection: Connection, 

1649 *, 

1650 schema: Optional[str] = None, 

1651 filter_names: Optional[Collection[str]] = None, 

1652 **kw: Any, 

1653 ) -> Iterable[Tuple[TableKey, List[ReflectedUniqueConstraint]]]: 

1654 """Return information about unique constraints in all tables 

1655 in the given ``schema``. 

1656 

1657 This is an internal dialect method. Applications should use 

1658 :meth:`.Inspector.get_multi_unique_constraints`. 

1659 

1660 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1661 implementation that will call the single table method for 

1662 each object returned by :meth:`Dialect.get_table_names`, 

1663 :meth:`Dialect.get_view_names` or 

1664 :meth:`Dialect.get_materialized_view_names` depending on the 

1665 provided ``kind``. Dialects that want to support a faster 

1666 implementation should implement this method. 

1667 

1668 .. versionadded:: 2.0 

1669 

1670 """ 

1671 

1672 raise NotImplementedError() 

1673 

1674 def get_check_constraints( 

1675 self, 

1676 connection: Connection, 

1677 table_name: str, 

1678 schema: Optional[str] = None, 

1679 **kw: Any, 

1680 ) -> List[ReflectedCheckConstraint]: 

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

1682 

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

1684 check constraint information as a list of dicts corresponding 

1685 to the :class:`.ReflectedCheckConstraint` dictionary. 

1686 

1687 This is an internal dialect method. Applications should use 

1688 :meth:`.Inspector.get_check_constraints`. 

1689 

1690 """ 

1691 

1692 raise NotImplementedError() 

1693 

1694 def get_multi_check_constraints( 

1695 self, 

1696 connection: Connection, 

1697 *, 

1698 schema: Optional[str] = None, 

1699 filter_names: Optional[Collection[str]] = None, 

1700 **kw: Any, 

1701 ) -> Iterable[Tuple[TableKey, List[ReflectedCheckConstraint]]]: 

1702 """Return information about check constraints in all tables 

1703 in the given ``schema``. 

1704 

1705 This is an internal dialect method. Applications should use 

1706 :meth:`.Inspector.get_multi_check_constraints`. 

1707 

1708 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1709 implementation that will call the single table method for 

1710 each object returned by :meth:`Dialect.get_table_names`, 

1711 :meth:`Dialect.get_view_names` or 

1712 :meth:`Dialect.get_materialized_view_names` depending on the 

1713 provided ``kind``. Dialects that want to support a faster 

1714 implementation should implement this method. 

1715 

1716 .. versionadded:: 2.0 

1717 

1718 """ 

1719 

1720 raise NotImplementedError() 

1721 

1722 def get_table_options( 

1723 self, 

1724 connection: Connection, 

1725 table_name: str, 

1726 schema: Optional[str] = None, 

1727 **kw: Any, 

1728 ) -> Dict[str, Any]: 

1729 """Return a dictionary of options specified when ``table_name`` 

1730 was created. 

1731 

1732 This is an internal dialect method. Applications should use 

1733 :meth:`_engine.Inspector.get_table_options`. 

1734 """ 

1735 raise NotImplementedError() 

1736 

1737 def get_multi_table_options( 

1738 self, 

1739 connection: Connection, 

1740 *, 

1741 schema: Optional[str] = None, 

1742 filter_names: Optional[Collection[str]] = None, 

1743 **kw: Any, 

1744 ) -> Iterable[Tuple[TableKey, Dict[str, Any]]]: 

1745 """Return a dictionary of options specified when the tables in the 

1746 given schema were created. 

1747 

1748 This is an internal dialect method. Applications should use 

1749 :meth:`_engine.Inspector.get_multi_table_options`. 

1750 

1751 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1752 implementation that will call the single table method for 

1753 each object returned by :meth:`Dialect.get_table_names`, 

1754 :meth:`Dialect.get_view_names` or 

1755 :meth:`Dialect.get_materialized_view_names` depending on the 

1756 provided ``kind``. Dialects that want to support a faster 

1757 implementation should implement this method. 

1758 

1759 .. versionadded:: 2.0 

1760 

1761 """ 

1762 raise NotImplementedError() 

1763 

1764 def get_table_comment( 

1765 self, 

1766 connection: Connection, 

1767 table_name: str, 

1768 schema: Optional[str] = None, 

1769 **kw: Any, 

1770 ) -> ReflectedTableComment: 

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

1772 

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

1774 table comment information as a dictionary corresponding to the 

1775 :class:`.ReflectedTableComment` dictionary. 

1776 

1777 This is an internal dialect method. Applications should use 

1778 :meth:`.Inspector.get_table_comment`. 

1779 

1780 :raise: ``NotImplementedError`` for dialects that don't support 

1781 comments. 

1782 

1783 .. versionadded:: 1.2 

1784 

1785 """ 

1786 

1787 raise NotImplementedError() 

1788 

1789 def get_multi_table_comment( 

1790 self, 

1791 connection: Connection, 

1792 *, 

1793 schema: Optional[str] = None, 

1794 filter_names: Optional[Collection[str]] = None, 

1795 **kw: Any, 

1796 ) -> Iterable[Tuple[TableKey, ReflectedTableComment]]: 

1797 """Return information about the table comment in all tables 

1798 in the given ``schema``. 

1799 

1800 This is an internal dialect method. Applications should use 

1801 :meth:`_engine.Inspector.get_multi_table_comment`. 

1802 

1803 .. note:: The :class:`_engine.DefaultDialect` provides a default 

1804 implementation that will call the single table method for 

1805 each object returned by :meth:`Dialect.get_table_names`, 

1806 :meth:`Dialect.get_view_names` or 

1807 :meth:`Dialect.get_materialized_view_names` depending on the 

1808 provided ``kind``. Dialects that want to support a faster 

1809 implementation should implement this method. 

1810 

1811 .. versionadded:: 2.0 

1812 

1813 """ 

1814 

1815 raise NotImplementedError() 

1816 

1817 def normalize_name(self, name: str) -> str: 

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

1819 case insensitive. 

1820 

1821 This method is only used if the dialect defines 

1822 requires_name_normalize=True. 

1823 

1824 """ 

1825 raise NotImplementedError() 

1826 

1827 def denormalize_name(self, name: str) -> str: 

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

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

1830 

1831 This method is only used if the dialect defines 

1832 requires_name_normalize=True. 

1833 

1834 """ 

1835 raise NotImplementedError() 

1836 

1837 def has_table( 

1838 self, 

1839 connection: Connection, 

1840 table_name: str, 

1841 schema: Optional[str] = None, 

1842 **kw: Any, 

1843 ) -> bool: 

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

1845 or view in the database. 

1846 

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

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

1849 database, False otherwise. 

1850 

1851 This method serves as the underlying implementation of the 

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

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

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

1855 

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

1857 published so that third-party dialects may provide an 

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

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

1860 

1861 .. versionchanged:: 2.0:: :meth:`_engine.Dialect.has_table` now 

1862 formally supports checking for additional table-like objects: 

1863 

1864 * any type of views (plain or materialized) 

1865 * temporary tables of any kind 

1866 

1867 Previously, these two checks were not formally specified and 

1868 different dialects would vary in their behavior. The dialect 

1869 testing suite now includes tests for all of these object types, 

1870 and dialects to the degree that the backing database supports views 

1871 or temporary tables should seek to support locating these objects 

1872 for full compliance. 

1873 

1874 """ 

1875 

1876 raise NotImplementedError() 

1877 

1878 def has_index( 

1879 self, 

1880 connection: Connection, 

1881 table_name: str, 

1882 index_name: str, 

1883 schema: Optional[str] = None, 

1884 **kw: Any, 

1885 ) -> bool: 

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

1887 

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

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

1890 the given name on the given table exists, ``False`` otherwise. 

1891 

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

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

1894 however dialects can implement a more performant version. 

1895 

1896 This is an internal dialect method. Applications should use 

1897 :meth:`_engine.Inspector.has_index`. 

1898 

1899 .. versionadded:: 1.4 

1900 

1901 """ 

1902 

1903 raise NotImplementedError() 

1904 

1905 def has_sequence( 

1906 self, 

1907 connection: Connection, 

1908 sequence_name: str, 

1909 schema: Optional[str] = None, 

1910 **kw: Any, 

1911 ) -> bool: 

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

1913 

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

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

1916 the database, ``False`` otherwise. 

1917 

1918 This is an internal dialect method. Applications should use 

1919 :meth:`_engine.Inspector.has_sequence`. 

1920 """ 

1921 

1922 raise NotImplementedError() 

1923 

1924 def has_schema( 

1925 self, connection: Connection, schema_name: str, **kw: Any 

1926 ) -> bool: 

1927 """Check the existence of a particular schema name in the database. 

1928 

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

1930 ``schema_name``, return ``True`` if a schema of the 

1931 given exists, ``False`` otherwise. 

1932 

1933 The :class:`.DefaultDialect` implements this by checking 

1934 the presence of ``schema_name`` among the schemas returned by 

1935 :meth:`.Dialect.get_schema_names`, 

1936 however dialects can implement a more performant version. 

1937 

1938 This is an internal dialect method. Applications should use 

1939 :meth:`_engine.Inspector.has_schema`. 

1940 

1941 .. versionadded:: 2.0 

1942 

1943 """ 

1944 

1945 raise NotImplementedError() 

1946 

1947 def _get_server_version_info(self, connection: Connection) -> Any: 

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

1949 

1950 This is used by the default implementation to populate the 

1951 "server_version_info" attribute and is called exactly 

1952 once upon first connect. 

1953 

1954 """ 

1955 

1956 raise NotImplementedError() 

1957 

1958 def _get_default_schema_name(self, connection: Connection) -> str: 

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

1960 the given connection. 

1961 

1962 This is used by the default implementation to populate the 

1963 "default_schema_name" attribute and is called exactly 

1964 once upon first connect. 

1965 

1966 """ 

1967 

1968 raise NotImplementedError() 

1969 

1970 def do_begin(self, dbapi_connection: PoolProxiedConnection) -> None: 

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

1972 DB-API connection. 

1973 

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

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

1976 DBAPIs that might need additional help in this area. 

1977 

1978 :param dbapi_connection: a DBAPI connection, typically 

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

1980 

1981 """ 

1982 

1983 raise NotImplementedError() 

1984 

1985 def do_rollback(self, dbapi_connection: PoolProxiedConnection) -> None: 

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

1987 a DB-API connection. 

1988 

1989 :param dbapi_connection: a DBAPI connection, typically 

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

1991 

1992 """ 

1993 

1994 raise NotImplementedError() 

1995 

1996 def do_commit(self, dbapi_connection: PoolProxiedConnection) -> None: 

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

1998 DB-API connection. 

1999 

2000 :param dbapi_connection: a DBAPI connection, typically 

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

2002 

2003 """ 

2004 

2005 raise NotImplementedError() 

2006 

2007 def do_terminate(self, dbapi_connection: DBAPIConnection) -> None: 

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

2009 much as possible to not block, given a DBAPI 

2010 connection. 

2011 

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

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

2014 

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

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

2017 

2018 .. versionadded:: 1.4.41 

2019 

2020 """ 

2021 

2022 raise NotImplementedError() 

2023 

2024 def do_close(self, dbapi_connection: DBAPIConnection) -> None: 

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

2026 connection. 

2027 

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

2029 when a connection has been 

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

2031 capacity of the pool. 

2032 

2033 """ 

2034 

2035 raise NotImplementedError() 

2036 

2037 def _do_ping_w_event(self, dbapi_connection: DBAPIConnection) -> bool: 

2038 raise NotImplementedError() 

2039 

2040 def do_ping(self, dbapi_connection: DBAPIConnection) -> bool: 

2041 """ping the DBAPI connection and return True if the connection is 

2042 usable.""" 

2043 raise NotImplementedError() 

2044 

2045 def do_set_input_sizes( 

2046 self, 

2047 cursor: DBAPICursor, 

2048 list_of_tuples: _GenericSetInputSizesType, 

2049 context: ExecutionContext, 

2050 ) -> Any: 

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

2052 

2053 This hook is called if the :attr:`.Dialect.bind_typing` attribute is 

2054 set to the 

2055 :attr:`.BindTyping.SETINPUTSIZES` value. 

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

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

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

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

2060 

2061 .. versionadded:: 1.4 

2062 

2063 .. versionchanged:: 2.0 - setinputsizes mode is now enabled by 

2064 setting :attr:`.Dialect.bind_typing` to 

2065 :attr:`.BindTyping.SETINPUTSIZES`. Dialects which accept 

2066 a ``use_setinputsizes`` parameter should set this value 

2067 appropriately. 

2068 

2069 

2070 """ 

2071 raise NotImplementedError() 

2072 

2073 def create_xid(self) -> Any: 

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

2075 

2076 This id will be passed to do_begin_twophase(), 

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

2078 unspecified. 

2079 """ 

2080 

2081 raise NotImplementedError() 

2082 

2083 def do_savepoint(self, connection: Connection, name: str) -> None: 

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

2085 

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

2087 :param name: savepoint name. 

2088 

2089 """ 

2090 

2091 raise NotImplementedError() 

2092 

2093 def do_rollback_to_savepoint( 

2094 self, connection: Connection, name: str 

2095 ) -> None: 

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

2097 

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

2099 :param name: savepoint name. 

2100 

2101 """ 

2102 

2103 raise NotImplementedError() 

2104 

2105 def do_release_savepoint(self, connection: Connection, name: str) -> None: 

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

2107 

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

2109 :param name: savepoint name. 

2110 """ 

2111 

2112 raise NotImplementedError() 

2113 

2114 def do_begin_twophase(self, connection: Connection, xid: Any) -> None: 

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

2116 

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

2118 :param xid: xid 

2119 

2120 """ 

2121 

2122 raise NotImplementedError() 

2123 

2124 def do_prepare_twophase(self, connection: Connection, xid: Any) -> None: 

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

2126 

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

2128 :param xid: xid 

2129 

2130 """ 

2131 

2132 raise NotImplementedError() 

2133 

2134 def do_rollback_twophase( 

2135 self, 

2136 connection: Connection, 

2137 xid: Any, 

2138 is_prepared: bool = True, 

2139 recover: bool = False, 

2140 ) -> None: 

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

2142 

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

2144 :param xid: xid 

2145 :param is_prepared: whether or not 

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

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

2148 

2149 """ 

2150 

2151 raise NotImplementedError() 

2152 

2153 def do_commit_twophase( 

2154 self, 

2155 connection: Connection, 

2156 xid: Any, 

2157 is_prepared: bool = True, 

2158 recover: bool = False, 

2159 ) -> None: 

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

2161 

2162 

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

2164 :param xid: xid 

2165 :param is_prepared: whether or not 

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

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

2168 

2169 """ 

2170 

2171 raise NotImplementedError() 

2172 

2173 def do_recover_twophase(self, connection: Connection) -> List[Any]: 

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

2175 identifiers on the given connection. 

2176 

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

2178 

2179 """ 

2180 

2181 raise NotImplementedError() 

2182 

2183 def _deliver_insertmanyvalues_batches( 

2184 self, 

2185 connection: Connection, 

2186 cursor: DBAPICursor, 

2187 statement: str, 

2188 parameters: _DBAPIMultiExecuteParams, 

2189 generic_setinputsizes: Optional[_GenericSetInputSizesType], 

2190 context: ExecutionContext, 

2191 ) -> Iterator[_InsertManyValuesBatch]: 

2192 """convert executemany parameters for an INSERT into an iterator 

2193 of statement/single execute values, used by the insertmanyvalues 

2194 feature. 

2195 

2196 """ 

2197 raise NotImplementedError() 

2198 

2199 def do_executemany( 

2200 self, 

2201 cursor: DBAPICursor, 

2202 statement: str, 

2203 parameters: _DBAPIMultiExecuteParams, 

2204 context: Optional[ExecutionContext] = None, 

2205 ) -> None: 

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

2207 parameters)``.""" 

2208 

2209 raise NotImplementedError() 

2210 

2211 def do_execute( 

2212 self, 

2213 cursor: DBAPICursor, 

2214 statement: str, 

2215 parameters: Optional[_DBAPISingleExecuteParams], 

2216 context: Optional[ExecutionContext] = None, 

2217 ) -> None: 

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

2219 parameters)``.""" 

2220 

2221 raise NotImplementedError() 

2222 

2223 def do_execute_no_params( 

2224 self, 

2225 cursor: DBAPICursor, 

2226 statement: str, 

2227 context: Optional[ExecutionContext] = None, 

2228 ) -> None: 

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

2230 

2231 The parameter collection should not be sent. 

2232 

2233 """ 

2234 

2235 raise NotImplementedError() 

2236 

2237 def is_disconnect( 

2238 self, 

2239 e: DBAPIModule.Error, 

2240 connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]], 

2241 cursor: Optional[DBAPICursor], 

2242 ) -> bool: 

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

2244 connection""" 

2245 

2246 raise NotImplementedError() 

2247 

2248 def connect(self, *cargs: Any, **cparams: Any) -> DBAPIConnection: 

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

2250 

2251 The default implementation of this method is:: 

2252 

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

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

2255 

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

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

2258 

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

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

2261 DBAPI. 

2262 

2263 

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

2265 :meth:`.Dialect.create_connect_args` method 

2266 

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

2268 :meth:`.Dialect.create_connect_args` method. 

2269 

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

2271 level ``.connect()`` function. 

2272 

2273 .. seealso:: 

2274 

2275 :meth:`.Dialect.create_connect_args` 

2276 

2277 :meth:`.Dialect.on_connect` 

2278 

2279 """ 

2280 raise NotImplementedError() 

2281 

2282 def on_connect_url(self, url: URL) -> Optional[Callable[[Any], Any]]: 

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

2284 

2285 This method is a new hook that supersedes the 

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

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

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

2289 compatibility with existing dialects. There is no deprecation 

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

2291 

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

2293 DBAPI connection itself. The inner callable has no 

2294 return value. 

2295 

2296 E.g.:: 

2297 

2298 class MyDialect(default.DefaultDialect): 

2299 # ... 

2300 

2301 def on_connect_url(self, url): 

2302 def do_on_connect(connection): 

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

2304 

2305 return do_on_connect 

2306 

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

2308 isolation modes, Unicode modes, etc. 

2309 

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

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

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

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

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

2315 replaced by plugins. 

2316 

2317 .. note:: 

2318 

2319 The default implementation of 

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

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

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

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

2324 it directly from here. 

2325 

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

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

2328 

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

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

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

2332 

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

2334 argument, or None. 

2335 

2336 .. seealso:: 

2337 

2338 :meth:`_engine.Dialect.on_connect` 

2339 

2340 """ 

2341 return self.on_connect() 

2342 

2343 def on_connect(self) -> Optional[Callable[[Any], None]]: 

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

2345 

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

2347 DBAPI connection itself. The inner callable has no 

2348 return value. 

2349 

2350 E.g.:: 

2351 

2352 class MyDialect(default.DefaultDialect): 

2353 # ... 

2354 

2355 def on_connect(self): 

2356 def do_on_connect(connection): 

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

2358 

2359 return do_on_connect 

2360 

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

2362 isolation modes, Unicode modes, etc. 

2363 

2364 The "do_on_connect" callable is invoked by using the 

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

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

2367 callable. 

2368 

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

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

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

2372 

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

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

2375 the connect args. Dialects can implement on_connect_url instead 

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

2377 connection in order to get additional context. 

2378 

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

2380 

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

2382 argument, or None. 

2383 

2384 .. seealso:: 

2385 

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

2387 itself to be controlled. 

2388 

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

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

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

2392 

2393 """ 

2394 return None 

2395 

2396 def reset_isolation_level(self, dbapi_connection: DBAPIConnection) -> None: 

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

2398 

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

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

2401 :class:`_engine.Engine` 

2402 isolation level facilities; these APIs should be preferred for 

2403 most typical use cases. 

2404 

2405 .. seealso:: 

2406 

2407 :meth:`_engine.Connection.get_isolation_level` 

2408 - view current level 

2409 

2410 :attr:`_engine.Connection.default_isolation_level` 

2411 - view default level 

2412 

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

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

2415 

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

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

2418 

2419 """ 

2420 

2421 raise NotImplementedError() 

2422 

2423 def set_isolation_level( 

2424 self, dbapi_connection: DBAPIConnection, level: IsolationLevel 

2425 ) -> None: 

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

2427 

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

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

2430 :class:`_engine.Engine` 

2431 isolation level facilities; these APIs should be preferred for 

2432 most typical use cases. 

2433 

2434 If the dialect also implements the 

2435 :meth:`.Dialect.get_isolation_level_values` method, then the given 

2436 level is guaranteed to be one of the string names within that sequence, 

2437 and the method will not need to anticipate a lookup failure. 

2438 

2439 .. seealso:: 

2440 

2441 :meth:`_engine.Connection.get_isolation_level` 

2442 - view current level 

2443 

2444 :attr:`_engine.Connection.default_isolation_level` 

2445 - view default level 

2446 

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

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

2449 

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

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

2452 

2453 """ 

2454 

2455 raise NotImplementedError() 

2456 

2457 def get_isolation_level( 

2458 self, dbapi_connection: DBAPIConnection 

2459 ) -> IsolationLevel: 

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

2461 

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

2463 the corresponding 

2464 DBAPI connection may be procured using the 

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

2466 

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

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

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

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

2471 

2472 

2473 .. seealso:: 

2474 

2475 :meth:`_engine.Connection.get_isolation_level` 

2476 - view current level 

2477 

2478 :attr:`_engine.Connection.default_isolation_level` 

2479 - view default level 

2480 

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

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

2483 

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

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

2486 

2487 

2488 """ 

2489 

2490 raise NotImplementedError() 

2491 

2492 def detect_autocommit_setting(self, dbapi_conn: DBAPIConnection) -> bool: 

2493 """Detect the current autocommit setting for a DBAPI connection. 

2494 

2495 :param dbapi_connection: a DBAPI connection object 

2496 :return: True if autocommit is enabled, False if disabled 

2497 :rtype: bool 

2498 

2499 This method inspects the given DBAPI connection to determine 

2500 whether autocommit mode is currently enabled. The specific 

2501 mechanism for detecting autocommit varies by database dialect 

2502 and DBAPI driver, however it should be done **without** network 

2503 round trips. 

2504 

2505 .. note:: 

2506 

2507 Not all dialects support autocommit detection. Dialects 

2508 that do not support this feature will raise 

2509 :exc:`NotImplementedError`. 

2510 

2511 """ 

2512 raise NotImplementedError( 

2513 "This dialect cannot detect autocommit on a DBAPI connection" 

2514 ) 

2515 

2516 def get_default_isolation_level( 

2517 self, dbapi_conn: DBAPIConnection 

2518 ) -> IsolationLevel: 

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

2520 a default isolation level if one cannot be retrieved. 

2521 

2522 This method may only raise NotImplementedError and 

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

2524 first connect. 

2525 

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

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

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

2529 

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

2531 method unless overridden by a dialect. 

2532 

2533 .. versionadded:: 1.3.22 

2534 

2535 """ 

2536 raise NotImplementedError() 

2537 

2538 def get_isolation_level_values( 

2539 self, dbapi_conn: DBAPIConnection 

2540 ) -> Sequence[IsolationLevel]: 

2541 """return a sequence of string isolation level names that are accepted 

2542 by this dialect. 

2543 

2544 The available names should use the following conventions: 

2545 

2546 * use UPPERCASE names. isolation level methods will accept lowercase 

2547 names but these are normalized into UPPERCASE before being passed 

2548 along to the dialect. 

2549 * separate words should be separated by spaces, not underscores, e.g. 

2550 ``REPEATABLE READ``. isolation level names will have underscores 

2551 converted to spaces before being passed along to the dialect. 

2552 * The names for the four standard isolation names to the extent that 

2553 they are supported by the backend should be ``READ UNCOMMITTED``, 

2554 ``READ COMMITTED``, ``REPEATABLE READ``, ``SERIALIZABLE`` 

2555 * if the dialect supports an autocommit option it should be provided 

2556 using the isolation level name ``AUTOCOMMIT``. 

2557 * Other isolation modes may also be present, provided that they 

2558 are named in UPPERCASE and use spaces not underscores. 

2559 

2560 This function is used so that the default dialect can check that 

2561 a given isolation level parameter is valid, else raises an 

2562 :class:`_exc.ArgumentError`. 

2563 

2564 A DBAPI connection is passed to the method, in the unlikely event that 

2565 the dialect needs to interrogate the connection itself to determine 

2566 this list, however it is expected that most backends will return 

2567 a hardcoded list of values. If the dialect supports "AUTOCOMMIT", 

2568 that value should also be present in the sequence returned. 

2569 

2570 The method raises ``NotImplementedError`` by default. If a dialect 

2571 does not implement this method, then the default dialect will not 

2572 perform any checking on a given isolation level value before passing 

2573 it onto the :meth:`.Dialect.set_isolation_level` method. This is 

2574 to allow backwards-compatibility with third party dialects that may 

2575 not yet be implementing this method. 

2576 

2577 .. versionadded:: 2.0 

2578 

2579 """ 

2580 raise NotImplementedError() 

2581 

2582 def _assert_and_set_isolation_level( 

2583 self, dbapi_conn: DBAPIConnection, level: IsolationLevel 

2584 ) -> None: 

2585 raise NotImplementedError() 

2586 

2587 @classmethod 

2588 def get_dialect_cls(cls, url: URL) -> Type[Dialect]: 

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

2590 

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

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

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

2594 the actual dialect to be used. 

2595 

2596 By default this just returns the cls. 

2597 

2598 """ 

2599 return cls 

2600 

2601 @classmethod 

2602 def get_async_dialect_cls(cls, url: URL) -> Type[Dialect]: 

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

2604 an async engine. 

2605 

2606 By default this is an alias of :meth:`.Dialect.get_dialect_cls` and 

2607 just returns the cls. It may be used if a dialect provides 

2608 both a sync and async version under the same name, like the 

2609 ``psycopg`` driver. 

2610 

2611 .. versionadded:: 2 

2612 

2613 .. seealso:: 

2614 

2615 :meth:`.Dialect.get_dialect_cls` 

2616 

2617 """ 

2618 return cls.get_dialect_cls(url) 

2619 

2620 @classmethod 

2621 def load_provisioning(cls) -> None: 

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

2623 

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

2625 provisioning followers, this method should initiate that process. 

2626 

2627 A typical implementation would be:: 

2628 

2629 @classmethod 

2630 def load_provisioning(cls): 

2631 __import__("mydialect.provision") 

2632 

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

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

2635 attribute:: 

2636 

2637 @classmethod 

2638 def load_provisioning(cls): 

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

2640 try: 

2641 __import__(package + ".provision") 

2642 except ImportError: 

2643 pass 

2644 

2645 .. versionadded:: 1.3.14 

2646 

2647 """ 

2648 

2649 @classmethod 

2650 def engine_created(cls, engine: Engine) -> None: 

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

2652 :class:`_engine.Engine`. 

2653 

2654 If the dialect returned a different class from the 

2655 :meth:`.get_dialect_cls` 

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

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

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

2659 

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

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

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

2663 

2664 """ 

2665 

2666 def get_driver_connection(self, connection: DBAPIConnection) -> Any: 

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

2668 package. 

2669 

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

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

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

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

2674 connection-like object as returned by the driver. 

2675 

2676 .. versionadded:: 1.4.24 

2677 

2678 """ 

2679 raise NotImplementedError() 

2680 

2681 def set_engine_execution_options( 

2682 self, engine: Engine, opts: CoreExecuteOptionsParameter 

2683 ) -> None: 

2684 """Establish execution options for a given engine. 

2685 

2686 This is implemented by :class:`.DefaultDialect` to establish 

2687 event hooks for new :class:`.Connection` instances created 

2688 by the given :class:`.Engine` which will then invoke the 

2689 :meth:`.Dialect.set_connection_execution_options` method for that 

2690 connection. 

2691 

2692 """ 

2693 raise NotImplementedError() 

2694 

2695 def set_connection_execution_options( 

2696 self, connection: Connection, opts: CoreExecuteOptionsParameter 

2697 ) -> None: 

2698 """Establish execution options for a given connection. 

2699 

2700 This is implemented by :class:`.DefaultDialect` in order to implement 

2701 the :paramref:`_engine.Connection.execution_options.isolation_level` 

2702 execution option. Dialects can intercept various execution options 

2703 which may need to modify state on a particular DBAPI connection. 

2704 

2705 .. versionadded:: 1.4 

2706 

2707 """ 

2708 raise NotImplementedError() 

2709 

2710 def get_dialect_pool_class(self, url: URL) -> Type[Pool]: 

2711 """return a Pool class to use for a given URL""" 

2712 raise NotImplementedError() 

2713 

2714 def validate_identifier(self, ident: str) -> None: 

2715 """Validates an identifier name, raising an exception if invalid""" 

2716 

2717 

2718class CreateEnginePlugin: 

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

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

2721 

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

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

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

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

2726 :class:`_engine.CreateEnginePlugin` include: 

2727 

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

2729 number of checkouts and/or time spent with statements 

2730 

2731 * connectivity plugins such as proxies 

2732 

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

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

2735 

2736 

2737 import logging 

2738 

2739 from sqlalchemy.engine import CreateEnginePlugin 

2740 from sqlalchemy import event 

2741 

2742 

2743 class LogCursorEventsPlugin(CreateEnginePlugin): 

2744 def __init__(self, url, kwargs): 

2745 # consume the parameter "log_cursor_logging_name" from the 

2746 # URL query 

2747 logging_name = url.query.get( 

2748 "log_cursor_logging_name", "log_cursor" 

2749 ) 

2750 

2751 self.log = logging.getLogger(logging_name) 

2752 

2753 def update_url(self, url): 

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

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

2756 

2757 def engine_created(self, engine): 

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

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

2760 

2761 def _log_event( 

2762 self, 

2763 conn, 

2764 cursor, 

2765 statement, 

2766 parameters, 

2767 context, 

2768 executemany, 

2769 ): 

2770 

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

2772 

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

2774 of dialects:: 

2775 

2776 entry_points = { 

2777 "sqlalchemy.plugins": [ 

2778 "log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin" 

2779 ] 

2780 } 

2781 

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

2783 URL as in:: 

2784 

2785 from sqlalchemy import create_engine 

2786 

2787 engine = create_engine( 

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

2789 "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger" 

2790 ) 

2791 

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

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

2794 in the URL:: 

2795 

2796 engine = create_engine( 

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

2798 "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three" 

2799 ) 

2800 

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

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

2803 

2804 engine = create_engine( 

2805 "mysql+pymysql://scott:tiger@localhost/test", plugins=["myplugin"] 

2806 ) 

2807 

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

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

2810 

2811 A plugin may consume plugin-specific arguments from the 

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

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

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

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

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

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

2818 

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

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

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

2822 should be consumed by implementing the 

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

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

2825 

2826 class MyPlugin(CreateEnginePlugin): 

2827 def __init__(self, url, kwargs): 

2828 self.my_argument_one = url.query["my_argument_one"] 

2829 self.my_argument_two = url.query["my_argument_two"] 

2830 self.my_argument_three = kwargs.pop("my_argument_three", None) 

2831 

2832 def update_url(self, url): 

2833 return url.difference_update_query( 

2834 ["my_argument_one", "my_argument_two"] 

2835 ) 

2836 

2837 Arguments like those illustrated above would be consumed from a 

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

2839 

2840 from sqlalchemy import create_engine 

2841 

2842 engine = create_engine( 

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

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

2845 my_argument_three="bat", 

2846 ) 

2847 

2848 .. versionchanged:: 1.4 

2849 

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

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

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

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

2854 is invoked after the plugin is constructed. 

2855 

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

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

2858 method to detect which version is running:: 

2859 

2860 class MyPlugin(CreateEnginePlugin): 

2861 def __init__(self, url, kwargs): 

2862 if hasattr(CreateEnginePlugin, "update_url"): 

2863 # detect the 1.4 API 

2864 self.my_argument_one = url.query["my_argument_one"] 

2865 self.my_argument_two = url.query["my_argument_two"] 

2866 else: 

2867 # detect the 1.3 and earlier API - mutate the 

2868 # URL directly 

2869 self.my_argument_one = url.query.pop("my_argument_one") 

2870 self.my_argument_two = url.query.pop("my_argument_two") 

2871 

2872 self.my_argument_three = kwargs.pop("my_argument_three", None) 

2873 

2874 def update_url(self, url): 

2875 # this method is only called in the 1.4 version 

2876 return url.difference_update_query( 

2877 ["my_argument_one", "my_argument_two"] 

2878 ) 

2879 

2880 .. seealso:: 

2881 

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

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

2884 

2885 

2886 When the engine creation process completes and produces the 

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

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

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

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

2891 

2892 """ # noqa: E501 

2893 

2894 def __init__(self, url: URL, kwargs: Dict[str, Any]): 

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

2896 

2897 The plugin object is instantiated individually for each call 

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

2899 Engine` will be 

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

2901 corresponding to this URL. 

2902 

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

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

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

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

2907 

2908 .. versionchanged:: 1.4 

2909 

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

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

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

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

2914 

2915 :param kwargs: The keyword arguments passed to 

2916 :func:`_sa.create_engine`. 

2917 

2918 """ 

2919 self.url = url 

2920 

2921 def update_url(self, url: URL) -> URL: 

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

2923 

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

2925 typically used to consume configuration arguments from the 

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

2927 recognized by the dialect. The 

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

2929 to remove these arguments. See the docstring at 

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

2931 

2932 

2933 .. versionadded:: 1.4 

2934 

2935 """ 

2936 raise NotImplementedError() 

2937 

2938 def handle_dialect_kwargs( 

2939 self, dialect_cls: Type[Dialect], dialect_args: Dict[str, Any] 

2940 ) -> None: 

2941 """parse and modify dialect kwargs""" 

2942 

2943 def handle_pool_kwargs( 

2944 self, pool_cls: Type[Pool], pool_args: Dict[str, Any] 

2945 ) -> None: 

2946 """parse and modify pool kwargs""" 

2947 

2948 def engine_created(self, engine: Engine) -> None: 

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

2950 object when it is fully constructed. 

2951 

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

2953 registering engine or connection pool events. 

2954 

2955 """ 

2956 

2957 

2958class ExecutionContext: 

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

2960 execution. 

2961 

2962 """ 

2963 

2964 engine: Engine 

2965 """engine which the Connection is associated with""" 

2966 

2967 connection: Connection 

2968 """Connection object which can be freely used by default value 

2969 generators to execute SQL. This Connection should reference the 

2970 same underlying connection/transactional resources of 

2971 root_connection.""" 

2972 

2973 root_connection: Connection 

2974 """Connection object which is the source of this ExecutionContext.""" 

2975 

2976 dialect: Dialect 

2977 """dialect which created this ExecutionContext.""" 

2978 

2979 cursor: DBAPICursor 

2980 """DB-API cursor procured from the connection""" 

2981 

2982 compiled: Optional[Compiled] 

2983 """if passed to constructor, sqlalchemy.engine.base.Compiled object 

2984 being executed""" 

2985 

2986 statement: str 

2987 """string version of the statement to be executed. Is either 

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

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

2990 

2991 invoked_statement: Optional[Executable] 

2992 """The Executable statement object that was given in the first place. 

2993 

2994 This should be structurally equivalent to compiled.statement, but not 

2995 necessarily the same object as in a caching scenario the compiled form 

2996 will have been extracted from the cache. 

2997 

2998 """ 

2999 

3000 parameters: _AnyMultiExecuteParams 

3001 """bind parameters passed to the execute() or exec_driver_sql() methods. 

3002 

3003 These are always stored as a list of parameter entries. A single-element 

3004 list corresponds to a ``cursor.execute()`` call and a multiple-element 

3005 list corresponds to ``cursor.executemany()``, except in the case 

3006 of :attr:`.ExecuteStyle.INSERTMANYVALUES` which will use 

3007 ``cursor.execute()`` one or more times. 

3008 

3009 """ 

3010 

3011 no_parameters: bool 

3012 """True if the execution style does not use parameters""" 

3013 

3014 isinsert: bool 

3015 """True if the statement is an INSERT.""" 

3016 

3017 isupdate: bool 

3018 """True if the statement is an UPDATE.""" 

3019 

3020 execute_style: ExecuteStyle 

3021 """the style of DBAPI cursor method that will be used to execute 

3022 a statement. 

3023 

3024 .. versionadded:: 2.0 

3025 

3026 """ 

3027 

3028 executemany: bool 

3029 """True if the context has a list of more than one parameter set. 

3030 

3031 Historically this attribute links to whether ``cursor.execute()`` or 

3032 ``cursor.executemany()`` will be used. It also can now mean that 

3033 "insertmanyvalues" may be used which indicates one or more 

3034 ``cursor.execute()`` calls. 

3035 

3036 """ 

3037 

3038 prefetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 

3039 """a list of Column objects for which a client-side default 

3040 was fired off. Applies to inserts and updates.""" 

3041 

3042 postfetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 

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

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

3045 and updates.""" 

3046 

3047 execution_options: _ExecuteOptions 

3048 """Execution options associated with the current statement execution""" 

3049 

3050 @classmethod 

3051 def _init_ddl( 

3052 cls, 

3053 dialect: Dialect, 

3054 connection: Connection, 

3055 dbapi_connection: PoolProxiedConnection, 

3056 execution_options: _ExecuteOptions, 

3057 compiled_ddl: DDLCompiler, 

3058 ) -> ExecutionContext: 

3059 raise NotImplementedError() 

3060 

3061 @classmethod 

3062 def _init_compiled( 

3063 cls, 

3064 dialect: Dialect, 

3065 connection: Connection, 

3066 dbapi_connection: PoolProxiedConnection, 

3067 execution_options: _ExecuteOptions, 

3068 compiled: SQLCompiler, 

3069 parameters: _CoreMultiExecuteParams, 

3070 invoked_statement: Executable, 

3071 extracted_parameters: Optional[Sequence[BindParameter[Any]]], 

3072 cache_hit: CacheStats = CacheStats.CACHING_DISABLED, 

3073 ) -> ExecutionContext: 

3074 raise NotImplementedError() 

3075 

3076 @classmethod 

3077 def _init_statement( 

3078 cls, 

3079 dialect: Dialect, 

3080 connection: Connection, 

3081 dbapi_connection: PoolProxiedConnection, 

3082 execution_options: _ExecuteOptions, 

3083 statement: str, 

3084 parameters: _DBAPIMultiExecuteParams, 

3085 ) -> ExecutionContext: 

3086 raise NotImplementedError() 

3087 

3088 @classmethod 

3089 def _init_default( 

3090 cls, 

3091 dialect: Dialect, 

3092 connection: Connection, 

3093 dbapi_connection: PoolProxiedConnection, 

3094 execution_options: _ExecuteOptions, 

3095 ) -> ExecutionContext: 

3096 raise NotImplementedError() 

3097 

3098 def _exec_default( 

3099 self, 

3100 column: Optional[Column[Any]], 

3101 default: DefaultGenerator, 

3102 type_: Optional[TypeEngine[Any]], 

3103 ) -> Any: 

3104 raise NotImplementedError() 

3105 

3106 def _prepare_set_input_sizes( 

3107 self, 

3108 ) -> Optional[List[Tuple[str, Any, TypeEngine[Any]]]]: 

3109 raise NotImplementedError() 

3110 

3111 def _get_cache_stats(self) -> str: 

3112 raise NotImplementedError() 

3113 

3114 def _setup_result_proxy(self) -> CursorResult[Any]: 

3115 raise NotImplementedError() 

3116 

3117 def fire_sequence(self, seq: Sequence_SchemaItem, type_: Integer) -> int: 

3118 """given a :class:`.Sequence`, invoke it and return the next int 

3119 value""" 

3120 raise NotImplementedError() 

3121 

3122 def create_cursor(self) -> DBAPICursor: 

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

3124 connection. 

3125 

3126 Some dialects may wish to change the behavior of 

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

3128 "server side" cursor. 

3129 """ 

3130 

3131 raise NotImplementedError() 

3132 

3133 def pre_exec(self) -> None: 

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

3135 

3136 If a compiled statement was passed to this ExecutionContext, 

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

3138 initialized after this statement is complete. 

3139 """ 

3140 

3141 raise NotImplementedError() 

3142 

3143 def get_out_parameter_values( 

3144 self, out_param_names: Sequence[str] 

3145 ) -> Sequence[Any]: 

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

3147 

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

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

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

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

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

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

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

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

3156 should set this flag explicitly. 

3157 

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

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

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

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

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

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

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

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

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

3167 transition. 

3168 

3169 .. versionadded:: 1.4 - added 

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

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

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

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

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

3175 

3176 """ 

3177 raise NotImplementedError() 

3178 

3179 def post_exec(self) -> None: 

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

3181 

3182 If a compiled statement was passed to this ExecutionContext, 

3183 the `last_insert_ids`, `last_inserted_params`, etc. 

3184 datamembers should be available after this method completes. 

3185 """ 

3186 

3187 raise NotImplementedError() 

3188 

3189 def handle_dbapi_exception(self, e: BaseException) -> None: 

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

3191 fetch, etc.""" 

3192 

3193 raise NotImplementedError() 

3194 

3195 def lastrow_has_defaults(self) -> bool: 

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

3197 inlined or database-side defaults. 

3198 """ 

3199 

3200 raise NotImplementedError() 

3201 

3202 def get_rowcount(self) -> Optional[int]: 

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

3204 cases an interpreted value. 

3205 

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

3207 

3208 """ 

3209 

3210 raise NotImplementedError() 

3211 

3212 def fetchall_for_returning(self, cursor: DBAPICursor) -> Sequence[Any]: 

3213 """For a RETURNING result, deliver cursor.fetchall() from the 

3214 DBAPI cursor. 

3215 

3216 This is a dialect-specific hook for dialects that have special 

3217 considerations when calling upon the rows delivered for a 

3218 "RETURNING" statement. Default implementation is 

3219 ``cursor.fetchall()``. 

3220 

3221 This hook is currently used only by the :term:`insertmanyvalues` 

3222 feature. Dialects that don't set ``use_insertmanyvalues=True`` 

3223 don't need to consider this hook. 

3224 

3225 .. versionadded:: 2.0.10 

3226 

3227 """ 

3228 raise NotImplementedError() 

3229 

3230 

3231class ConnectionEventsTarget(EventTarget): 

3232 """An object which can accept events from :class:`.ConnectionEvents`. 

3233 

3234 Includes :class:`_engine.Connection` and :class:`_engine.Engine`. 

3235 

3236 .. versionadded:: 2.0 

3237 

3238 """ 

3239 

3240 dispatch: dispatcher[ConnectionEventsTarget] 

3241 

3242 

3243Connectable = ConnectionEventsTarget 

3244 

3245 

3246class ExceptionContext: 

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

3248 

3249 This object exists solely to be passed to the 

3250 :meth:`_events.DialectEvents.handle_error` event, 

3251 supporting an interface that 

3252 can be extended without backwards-incompatibility. 

3253 

3254 

3255 """ 

3256 

3257 __slots__ = () 

3258 

3259 dialect: Dialect 

3260 """The :class:`_engine.Dialect` in use. 

3261 

3262 This member is present for all invocations of the event hook. 

3263 

3264 .. versionadded:: 2.0 

3265 

3266 """ 

3267 

3268 connection: Optional[Connection] 

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

3270 

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

3272 first connecting. 

3273 

3274 .. seealso:: 

3275 

3276 :attr:`.ExceptionContext.engine` 

3277 

3278 

3279 """ 

3280 

3281 engine: Optional[Engine] 

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

3283 

3284 This member is present in all cases except for when handling an error 

3285 within the connection pool "pre-ping" process. 

3286 

3287 """ 

3288 

3289 cursor: Optional[DBAPICursor] 

3290 """The DBAPI cursor object. 

3291 

3292 May be None. 

3293 

3294 """ 

3295 

3296 statement: Optional[str] 

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

3298 

3299 May be None. 

3300 

3301 """ 

3302 

3303 parameters: Optional[_DBAPIAnyExecuteParams] 

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

3305 

3306 May be None. 

3307 

3308 """ 

3309 

3310 original_exception: BaseException 

3311 """The exception object which was caught. 

3312 

3313 This member is always present. 

3314 

3315 """ 

3316 

3317 sqlalchemy_exception: Optional[StatementError] 

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

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

3320 

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

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

3323 field will always be present. 

3324 

3325 """ 

3326 

3327 chained_exception: Optional[BaseException] 

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

3329 exception chain, if any. 

3330 

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

3332 SQLAlchemy unless a subsequent handler replaces it. 

3333 

3334 May be None. 

3335 

3336 """ 

3337 

3338 execution_context: Optional[ExecutionContext] 

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

3340 operation in progress. 

3341 

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

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

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

3345 could be constructed. 

3346 

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

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

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

3350 potentially in the case where a 

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

3352 modified the statement/parameters to be sent. 

3353 

3354 May be None. 

3355 

3356 """ 

3357 

3358 is_disconnect: bool 

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

3360 condition. 

3361 

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

3363 :meth:`_events.DialectEvents.handle_error` handler. 

3364 

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

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

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

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

3369 changing this flag. 

3370 

3371 

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

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

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

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

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

3377 <pool_disconnects_pessimistic_custom>`. A future API allow more 

3378 comprehensive customization of the "disconnect" detection mechanism 

3379 across all functions. 

3380 

3381 """ 

3382 

3383 invalidate_pool_on_disconnect: bool 

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

3385 when a "disconnect" condition is in effect. 

3386 

3387 Setting this flag to False within the scope of the 

3388 :meth:`_events.DialectEvents.handle_error` 

3389 event will have the effect such 

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

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

3392 subject of the error will actually be invalidated. 

3393 

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

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

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

3397 

3398 """ 

3399 

3400 is_pre_ping: bool 

3401 """Indicates if this error is occurring within the "pre-ping" step 

3402 performed when :paramref:`_sa.create_engine.pool_pre_ping` is set to 

3403 ``True``. In this mode, the :attr:`.ExceptionContext.engine` attribute 

3404 will be ``None``. The dialect in use is accessible via the 

3405 :attr:`.ExceptionContext.dialect` attribute. 

3406 

3407 .. versionadded:: 2.0.5 

3408 

3409 """ 

3410 

3411 

3412class AdaptedConnection: 

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

3414 

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

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

3417 

3418 .. versionadded:: 1.4.24 

3419 

3420 """ 

3421 

3422 __slots__ = ("_connection",) 

3423 

3424 _connection: AsyncIODBAPIConnection 

3425 

3426 @property 

3427 def driver_connection(self) -> Any: 

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

3429 return self._connection 

3430 

3431 def run_async(self, fn: Callable[[Any], Awaitable[_T]]) -> _T: 

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

3433 the raw asyncio driver connection. 

3434 

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

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

3437 pool event handler. 

3438 

3439 E.g.:: 

3440 

3441 engine = create_async_engine(...) 

3442 

3443 

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

3445 def register_custom_types( 

3446 dbapi_connection, # ... 

3447 ): 

3448 dbapi_connection.run_async( 

3449 lambda connection: connection.set_type_codec( 

3450 "MyCustomType", encoder, decoder, ... 

3451 ) 

3452 ) 

3453 

3454 .. versionadded:: 1.4.30 

3455 

3456 .. seealso:: 

3457 

3458 :ref:`asyncio_events_run_async` 

3459 

3460 """ 

3461 return await_only(fn(self._connection)) 

3462 

3463 def __repr__(self) -> str: 

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