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

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

707 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 Literal 

23from typing import Mapping 

24from typing import MutableMapping 

25from typing import Optional 

26from typing import Protocol 

27from typing import Sequence 

28from typing import Set 

29from typing import Tuple 

30from typing import Type 

31from typing import TYPE_CHECKING 

32from typing import TypedDict 

33from typing import TypeVar 

34from typing import Union 

35 

36from .. import util 

37from ..event import EventTarget 

38from ..pool import Pool 

39from ..pool import PoolProxiedConnection as PoolProxiedConnection 

40from ..sql.compiler import Compiled as Compiled 

41from ..sql.compiler import Compiled # noqa 

42from ..sql.compiler import TypeCompiler as TypeCompiler 

43from ..sql.compiler import TypeCompiler # noqa 

44from ..util import immutabledict 

45from ..util.concurrency import await_ 

46from ..util.typing import NotRequired 

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 AggregateOrderByStyle 

60 from ..sql.compiler import DDLCompiler 

61 from ..sql.compiler import IdentifierPreparer 

62 from ..sql.compiler import InsertmanyvaluesSentinelOpts 

63 from ..sql.compiler import Linting 

64 from ..sql.compiler import SQLCompiler 

65 from ..sql.elements import BindParameter 

66 from ..sql.elements import ClauseElement 

67 from ..sql.schema import Column 

68 from ..sql.schema import DefaultGenerator 

69 from ..sql.schema import SchemaItem 

70 from ..sql.schema import Sequence as Sequence_SchemaItem 

71 from ..sql.sqltypes import Integer 

72 from ..sql.type_api import _TypeMemoDict 

73 from ..sql.type_api import TypeEngine 

74 from ..util.langhelpers import generic_fn_descriptor 

75 

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

77 

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

79 

80 

81class CacheStats(Enum): 

82 CACHE_HIT = 0 

83 CACHE_MISS = 1 

84 CACHING_DISABLED = 2 

85 NO_CACHE_KEY = 3 

86 NO_DIALECT_SUPPORT = 4 

87 

88 

89class ExecuteStyle(Enum): 

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

91 a statement.""" 

92 

93 EXECUTE = 0 

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

95 

96 EXECUTEMANY = 1 

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

98 

99 INSERTMANYVALUES = 2 

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

101 VALUES expression will be expanded to accommodate for multiple 

102 parameter sets 

103 

104 .. seealso:: 

105 

106 :ref:`engine_insertmanyvalues` 

107 

108 """ 

109 

110 

111class DBAPIModule(Protocol): 

112 class Error(Exception): 

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

114 

115 class OperationalError(Error): 

116 pass 

117 

118 class InterfaceError(Error): 

119 pass 

120 

121 class IntegrityError(Error): 

122 pass 

123 

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

125 

126 

127class DBAPIConnection(Protocol): 

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

129 

130 .. versionadded:: 2.0 

131 

132 .. seealso:: 

133 

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

135 - in :pep:`249` 

136 

137 """ # noqa: E501 

138 

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

140 

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

142 

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

144 

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

146 

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

148 

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

150 

151 

152class DBAPIType(Protocol): 

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

154 

155 .. versionadded:: 2.0 

156 

157 .. seealso:: 

158 

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

160 - in :pep:`249` 

161 

162 """ # noqa: E501 

163 

164 

165class DBAPICursor(Protocol): 

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

167 

168 .. versionadded:: 2.0 

169 

170 .. seealso:: 

171 

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

173 - in :pep:`249` 

174 

175 """ # noqa: E501 

176 

177 @property 

178 def description( 

179 self, 

180 ) -> _DBAPICursorDescription: 

181 """The description attribute of the Cursor. 

182 

183 .. seealso:: 

184 

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

186 - in :pep:`249` 

187 

188 

189 """ # noqa: E501 

190 ... 

191 

192 @property 

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

194 

195 arraysize: int 

196 

197 lastrowid: int 

198 

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

200 

201 def execute( 

202 self, 

203 operation: Any, 

204 parameters: Optional[_DBAPISingleExecuteParams] = None, 

205 ) -> Any: ... 

206 

207 def executemany( 

208 self, 

209 operation: Any, 

210 parameters: _DBAPIMultiExecuteParams, 

211 ) -> Any: ... 

212 

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

214 

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

216 

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

218 

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

220 

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

222 

223 def callproc( 

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

225 ) -> Any: ... 

226 

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

228 

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

230 

231 

232_CoreSingleExecuteParams = Mapping[str, Any] 

233_MutableCoreSingleExecuteParams = MutableMapping[str, Any] 

234_CoreMultiExecuteParams = Sequence[_CoreSingleExecuteParams] 

235_CoreAnyExecuteParams = Union[ 

236 _CoreMultiExecuteParams, _CoreSingleExecuteParams 

237] 

238 

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

240 

241_DBAPIMultiExecuteParams = Union[ 

242 Sequence[Sequence[Any]], _CoreMultiExecuteParams 

243] 

244_DBAPIAnyExecuteParams = Union[ 

245 _DBAPIMultiExecuteParams, _DBAPISingleExecuteParams 

246] 

247_DBAPICursorDescription = Sequence[ 

248 Tuple[ 

249 str, 

250 "DBAPIType", 

251 Optional[int], 

252 Optional[int], 

253 Optional[int], 

254 Optional[int], 

255 Optional[bool], 

256 ] 

257] 

258 

259_AnySingleExecuteParams = _DBAPISingleExecuteParams 

260_AnyMultiExecuteParams = _DBAPIMultiExecuteParams 

261_AnyExecuteParams = _DBAPIAnyExecuteParams 

262 

263CompiledCacheType = MutableMapping[Any, "Compiled"] 

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

265 

266_ImmutableExecuteOptions = immutabledict[str, Any] 

267 

268_ParamStyle = Literal[ 

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

270] 

271 

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

273 

274IsolationLevel = Literal[ 

275 "SERIALIZABLE", 

276 "REPEATABLE READ", 

277 "READ COMMITTED", 

278 "READ UNCOMMITTED", 

279 "AUTOCOMMIT", 

280] 

281 

282 

283class _CoreKnownExecutionOptions(TypedDict, total=False): 

284 compiled_cache: Optional[CompiledCacheType] 

285 logging_token: str 

286 isolation_level: IsolationLevel 

287 no_parameters: bool 

288 stream_results: bool 

289 max_row_buffer: int 

290 yield_per: int 

291 insertmanyvalues_page_size: int 

292 schema_translate_map: Optional[SchemaTranslateMapType] 

293 preserve_rowcount: bool 

294 driver_column_names: bool 

295 

296 

297_ExecuteOptions = immutabledict[str, Any] 

298CoreExecuteOptionsParameter = Union[ 

299 _CoreKnownExecutionOptions, Mapping[str, Any] 

300] 

301 

302 

303class ReflectedIdentity(TypedDict): 

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

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

306 

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

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

309 :meth:`.Inspector.get_columns` method. 

310 

311 """ 

312 

313 always: bool 

314 """type of identity column""" 

315 

316 on_null: bool 

317 """indicates ON NULL""" 

318 

319 start: int 

320 """starting index of the sequence""" 

321 

322 increment: int 

323 """increment value of the sequence""" 

324 

325 minvalue: int 

326 """the minimum value of the sequence.""" 

327 

328 maxvalue: int 

329 """the maximum value of the sequence.""" 

330 

331 nominvalue: bool 

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

333 

334 nomaxvalue: bool 

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

336 

337 cycle: bool 

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

339 or minvalue has been reached.""" 

340 

341 cache: Optional[int] 

342 """number of future values in the 

343 sequence which are calculated in advance.""" 

344 

345 order: bool 

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

347 

348 

349class ReflectedComputed(TypedDict): 

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

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

352 

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

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

355 :meth:`.Inspector.get_columns` method. 

356 

357 """ 

358 

359 sqltext: str 

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

361 as a string SQL expression""" 

362 

363 persisted: NotRequired[bool] 

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

365 

366 

367class ReflectedColumn(TypedDict): 

368 """Dictionary representing the reflected elements corresponding to 

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

370 

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

372 :class:`.Inspector.get_columns` method. 

373 

374 """ 

375 

376 name: str 

377 """column name""" 

378 

379 type: TypeEngine[Any] 

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

381 

382 nullable: bool 

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

384 

385 default: Optional[str] 

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

387 

388 autoincrement: NotRequired[bool] 

389 """database-dependent autoincrement flag. 

390 

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

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

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

394 such a flag on them. 

395 

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

397 "autoincrement". 

398 

399 """ 

400 

401 comment: NotRequired[Optional[str]] 

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

403 Only some dialects return this key 

404 """ 

405 

406 computed: NotRequired[ReflectedComputed] 

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

408 Only some dialects return this key. 

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 

453 

454class ReflectedUniqueConstraint(ReflectedConstraint): 

455 """Dictionary representing the reflected elements corresponding to 

456 :class:`.UniqueConstraint`. 

457 

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

459 :meth:`.Inspector.get_unique_constraints` method. 

460 

461 """ 

462 

463 column_names: List[str] 

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

465 

466 duplicates_index: NotRequired[Optional[str]] 

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

468 

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

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

471 constraint""" 

472 

473 

474class ReflectedPrimaryKeyConstraint(ReflectedConstraint): 

475 """Dictionary representing the reflected elements corresponding to 

476 :class:`.PrimaryKeyConstraint`. 

477 

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

479 :meth:`.Inspector.get_pk_constraint` method. 

480 

481 """ 

482 

483 constrained_columns: List[str] 

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

485 

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

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

488 

489 

490class ReflectedForeignKeyConstraint(ReflectedConstraint): 

491 """Dictionary representing the reflected elements corresponding to 

492 :class:`.ForeignKeyConstraint`. 

493 

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

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

496 

497 """ 

498 

499 constrained_columns: List[str] 

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

501 

502 referred_schema: Optional[str] 

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

504 

505 referred_table: str 

506 """name of the table being referred""" 

507 

508 referred_columns: List[str] 

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

510 

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

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

513 

514 

515class ReflectedIndex(TypedDict): 

516 """Dictionary representing the reflected elements corresponding to 

517 :class:`.Index`. 

518 

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

520 :meth:`.Inspector.get_indexes` method. 

521 

522 """ 

523 

524 name: Optional[str] 

525 """index name""" 

526 

527 column_names: List[Optional[str]] 

528 """column names which the index references. 

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

530 returned in the ``expressions`` list. 

531 """ 

532 

533 expressions: NotRequired[List[str]] 

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

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

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

537 """ 

538 

539 unique: bool 

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

541 

542 duplicates_constraint: NotRequired[Optional[str]] 

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

544 

545 include_columns: NotRequired[List[str]] 

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

547 

548 .. deprecated:: 2.0 

549 

550 Legacy value, will be replaced with 

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

552 

553 """ 

554 

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

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

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

558 ``nulls_last``. 

559 """ 

560 

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

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

563 

564 

565class ReflectedTableComment(TypedDict): 

566 """Dictionary representing the reflected comment corresponding to 

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

568 

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

570 :meth:`.Inspector.get_table_comment` method. 

571 

572 """ 

573 

574 text: Optional[str] 

575 """text of the comment""" 

576 

577 

578class BindTyping(Enum): 

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

580 bound parameters in a statement to the database driver. 

581 

582 .. versionadded:: 2.0 

583 

584 """ 

585 

586 NONE = 1 

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

588 

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

590 SQL Server. 

591 

592 """ 

593 

594 SETINPUTSIZES = 2 

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

596 

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

598 the SQLAlchemy dialect has the appropriate infrastructure for that dialect 

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

600 optional support for SQL Server using pyodbc. 

601 

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

603 method for certain datatypes using include/exclude lists. 

604 

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

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

607 

608 """ 

609 

610 RENDER_CASTS = 3 

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

612 

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

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

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

616 aren't. 

617 

618 When RENDER_CASTS is used, the compiler will invoke the 

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

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

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

622 

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

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

625 :attr:`.InsertmanyvaluesSentinelOpts.USE_INSERT_FROM_SELECT` and 

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

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

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

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

630 

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

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

633 

634 

635 """ 

636 

637 

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

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

640 

641 

642class Dialect(EventTarget): 

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

644 

645 Any aspect of metadata definition, SQL query generation, 

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

647 between databases is defined under the general category of the 

648 Dialect. The Dialect acts as a factory for other 

649 database-specific object implementations including 

650 ExecutionContext, Compiled, DefaultGenerator, and TypeEngine. 

651 

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

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

654 descendant class. 

655 

656 """ 

657 

658 CACHE_HIT = CacheStats.CACHE_HIT 

659 CACHE_MISS = CacheStats.CACHE_MISS 

660 CACHING_DISABLED = CacheStats.CACHING_DISABLED 

661 NO_CACHE_KEY = CacheStats.NO_CACHE_KEY 

662 NO_DIALECT_SUPPORT = CacheStats.NO_DIALECT_SUPPORT 

663 

664 dispatch: dispatcher[Dialect] 

665 

666 name: str 

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

668 (i.e. 'sqlite') 

669 """ 

670 

671 driver: str 

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

673 

674 dialect_description: str 

675 

676 dbapi: Optional[DBAPIModule] 

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

678 

679 SQLAlchemy dialects import DBAPI modules using the classmethod 

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

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

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

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

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

685 the DBAPI module to this attribute. 

686 

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

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

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

690 contents. 

691 

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

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

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

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

696 

697 """ 

698 

699 @util.non_memoized_property 

700 def loaded_dbapi(self) -> DBAPIModule: 

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

702 DBAPI was set up. 

703 

704 .. versionadded:: 2.0 

705 

706 """ 

707 raise NotImplementedError() 

708 

709 positional: bool 

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

711 

712 paramstyle: str 

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

714 paramstyles). 

715 """ 

716 

717 compiler_linting: Linting 

718 

719 statement_compiler: Type[SQLCompiler] 

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

721 

722 ddl_compiler: Type[DDLCompiler] 

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

724 

725 type_compiler_cls: ClassVar[Type[TypeCompiler]] 

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

727 

728 .. versionadded:: 2.0 

729 

730 """ 

731 

732 type_compiler_instance: TypeCompiler 

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

734 objects 

735 

736 .. versionadded:: 2.0 

737 

738 """ 

739 

740 type_compiler: Any 

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

742 TypeCompiler instance at the instance level. 

743 

744 Refer to type_compiler_instance instead. 

745 

746 """ 

747 

748 preparer: Type[IdentifierPreparer] 

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

750 quote identifiers. 

751 """ 

752 

753 identifier_preparer: IdentifierPreparer 

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

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

756 

757 """ 

758 

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

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

761 

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

763 typically populated during the initial connection to the database. 

764 """ 

765 

766 default_schema_name: Optional[str] 

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

768 supporting dialects, and is typically populated during the 

769 initial connection to the database. 

770 

771 """ 

772 

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

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

775 default_isolation_level: Optional[IsolationLevel] 

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

777 

778 skip_autocommit_rollback: bool 

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

780 parameter was set. 

781 

782 .. versionadded:: 2.0.43 

783 

784 """ 

785 

786 # create_engine() -> isolation_level currently goes here 

787 _on_connect_isolation_level: Optional[IsolationLevel] 

788 

789 execution_ctx_cls: Type[ExecutionContext] 

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

791 

792 execute_sequence_format: Union[ 

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

794 ] 

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

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

797 

798 supports_alter: bool 

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

800 generating foreign key constraints in certain circumstances 

801 """ 

802 

803 max_identifier_length: int 

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

805 max_index_name_length: Optional[int] 

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

807 ``max_identifier_length``.""" 

808 max_constraint_name_length: Optional[int] 

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

810 ``max_identifier_length``.""" 

811 

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

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

814 

815 server_side_cursors: bool 

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

817 side cursors by default""" 

818 

819 supports_sane_rowcount: bool 

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

821 ``UPDATE`` and ``DELETE`` statements. 

822 """ 

823 

824 supports_sane_multi_rowcount: bool 

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

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

827 executemany. 

828 """ 

829 

830 supports_empty_insert: bool 

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

832 columns in it. 

833 

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

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

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

837 

838 """ 

839 

840 supports_default_values: bool 

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

842 

843 supports_default_metavalue: bool 

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

845 

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

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

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

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

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

851 

852 """ 

853 

854 default_metavalue_token: str = "DEFAULT" 

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

856 parenthesis. 

857 

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

859 

860 """ 

861 

862 supports_multivalues_insert: bool 

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

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

865 

866 """ 

867 

868 aggregate_order_by_style: AggregateOrderByStyle 

869 """Style of ORDER BY supported for arbitrary aggregate functions 

870 

871 .. versionadded:: 2.1 

872 

873 """ 

874 

875 insert_executemany_returning: bool 

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

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

878 

879 """ 

880 

881 insert_executemany_returning_sort_by_parameter_order: bool 

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

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

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

885 parameter being set. 

886 

887 """ 

888 

889 update_executemany_returning: bool 

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

891 

892 delete_executemany_returning: bool 

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

894 

895 use_insertmanyvalues: bool 

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

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

898 

899 In practice, setting this to True means: 

900 

901 if ``supports_multivalues_insert``, ``insert_returning`` and 

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

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

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

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

906 INSERT statement to have multiple VALUES clauses, also executing 

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

908 of rows are given. 

909 

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

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

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

913 with RETURNING" support and also does not support 

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

915 that don't support RETURNING will not report 

916 ``insert_executemany_returning`` as True. 

917 

918 .. versionadded:: 2.0 

919 

920 .. seealso:: 

921 

922 :ref:`engine_insertmanyvalues` 

923 

924 """ 

925 

926 use_insertmanyvalues_wo_returning: bool 

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

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

929 

930 .. versionadded:: 2.0 

931 

932 .. seealso:: 

933 

934 :ref:`engine_insertmanyvalues` 

935 

936 """ 

937 

938 insertmanyvalues_implicit_sentinel: InsertmanyvaluesSentinelOpts 

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

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

941 for INSERTed rows. 

942 

943 .. versionadded:: 2.0.10 

944 

945 .. seealso:: 

946 

947 :ref:`engine_insertmanyvalues_returning_order` 

948 

949 """ 

950 

951 insertmanyvalues_page_size: int 

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

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

954 

955 The default dialect defaults this to 1000. 

956 

957 .. versionadded:: 2.0 

958 

959 .. seealso:: 

960 

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

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

963 

964 """ # noqa: E501 

965 

966 insertmanyvalues_max_parameters: int 

967 """Alternate to insertmanyvalues_page_size, will additionally limit 

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

969 

970 

971 """ 

972 

973 preexecute_autoincrement_sequences: bool 

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

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

976 

977 This is currently oriented towards PostgreSQL when the 

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

979 object. 

980 

981 """ 

982 

983 insert_returning: bool 

984 """if the dialect supports RETURNING with INSERT 

985 

986 .. versionadded:: 2.0 

987 

988 """ 

989 

990 update_returning: bool 

991 """if the dialect supports RETURNING with UPDATE 

992 

993 .. versionadded:: 2.0 

994 

995 """ 

996 

997 update_returning_multifrom: bool 

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

999 

1000 .. versionadded:: 2.0 

1001 

1002 """ 

1003 

1004 delete_returning: bool 

1005 """if the dialect supports RETURNING with DELETE 

1006 

1007 .. versionadded:: 2.0 

1008 

1009 """ 

1010 

1011 delete_returning_multifrom: bool 

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

1013 

1014 .. versionadded:: 2.0 

1015 

1016 """ 

1017 

1018 favor_returning_over_lastrowid: bool 

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

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

1021 

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

1023 

1024 """ 

1025 

1026 supports_identity_columns: bool 

1027 """target database supports IDENTITY""" 

1028 

1029 cte_follows_insert: bool 

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

1031 the CTE to be below the INSERT""" 

1032 

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

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

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

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

1037 dialect instance itself. 

1038 """ 

1039 

1040 supports_sequences: bool 

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

1042 

1043 sequences_optional: bool 

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

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

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

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

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

1049 other backends. 

1050 """ 

1051 

1052 default_sequence_base: int 

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

1054 a CREATE SEQUENCE DDL statement. 

1055 

1056 """ 

1057 

1058 supports_native_enum: bool 

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

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

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

1062 """ 

1063 

1064 supports_native_boolean: bool 

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

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

1067 constraint when that type is used. 

1068 """ 

1069 

1070 supports_native_decimal: bool 

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

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

1073 

1074 supports_native_uuid: bool 

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

1076 driver for SQL UUID datatypes. 

1077 

1078 .. versionadded:: 2.0 

1079 

1080 """ 

1081 

1082 returns_native_bytes: bool 

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

1084 driver for SQL "binary" datatypes. 

1085 

1086 .. versionadded:: 2.0.11 

1087 

1088 """ 

1089 

1090 construct_arguments: Optional[ 

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

1092 ] = None 

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

1094 constructs, typically schema items. 

1095 

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

1097 

1098 construct_arguments = [ 

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

1100 ] 

1101 

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

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

1104 ``postgresql_using``, ``postgresql_where``, nad ``postgresql_ops``. 

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

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

1107 

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

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

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

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

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

1113 feature continue to function in the old way. 

1114 

1115 .. seealso:: 

1116 

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

1118 :attr:`.DefaultDialect.construct_arguments` 

1119 

1120 

1121 """ 

1122 

1123 reflection_options: Sequence[str] = () 

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

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

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

1127 

1128 Current example is "oracle_resolve_synonyms" in the Oracle Database 

1129 dialects. 

1130 

1131 """ 

1132 

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

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

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

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

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

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

1139 majority of cases this dictionary is empty. 

1140 """ 

1141 

1142 supports_comments: bool 

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

1144 

1145 inline_comments: bool 

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

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

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

1149 

1150 supports_constraint_comments: bool 

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

1152 

1153 .. versionadded:: 2.0 

1154 """ 

1155 

1156 _has_events = False 

1157 

1158 supports_statement_cache: bool = True 

1159 """indicates if this dialect supports caching. 

1160 

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

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

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

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

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

1166 compliant with SQL statement caching. 

1167 

1168 .. versionadded:: 1.4.5 

1169 

1170 .. seealso:: 

1171 

1172 :ref:`engine_thirdparty_caching` 

1173 

1174 """ 

1175 

1176 _supports_statement_cache: bool 

1177 """internal evaluation for supports_statement_cache""" 

1178 

1179 bind_typing = BindTyping.NONE 

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

1181 driver for bound parameters. 

1182 

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

1184 

1185 .. versionadded:: 2.0 

1186 

1187 """ 

1188 

1189 is_async: bool 

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

1191 

1192 has_terminate: bool 

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

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

1195 

1196 engine_config_types: Mapping[str, Any] 

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

1198 type conversion functions. 

1199 

1200 """ 

1201 

1202 label_length: Optional[int] 

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

1204 

1205 include_set_input_sizes: Optional[Set[Any]] 

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

1207 automatic cursor.setinputsizes() calls. 

1208 

1209 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 

1210 

1211 """ 

1212 

1213 exclude_set_input_sizes: Optional[Set[Any]] 

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

1215 automatic cursor.setinputsizes() calls. 

1216 

1217 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 

1218 

1219 """ 

1220 

1221 supports_simple_order_by_label: bool 

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

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

1224 

1225 div_is_floordiv: bool 

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

1227 

1228 tuple_in_values: bool 

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

1230 

1231 _bind_typing_render_casts: bool 

1232 

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

1234 

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

1236 raise NotImplementedError() 

1237 

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

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

1240 

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

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

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

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

1245 ``connect()`` function. 

1246 

1247 The method typically makes use of the 

1248 :meth:`.URL.translate_connect_args` 

1249 method in order to generate a dictionary of options. 

1250 

1251 The default implementation is:: 

1252 

1253 def create_connect_args(self, url): 

1254 opts = url.translate_connect_args() 

1255 opts.update(url.query) 

1256 return ([], opts) 

1257 

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

1259 

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

1261 :meth:`.Dialect.connect` method. 

1262 

1263 .. seealso:: 

1264 

1265 :meth:`.URL.translate_connect_args` 

1266 

1267 """ 

1268 

1269 raise NotImplementedError() 

1270 

1271 @classmethod 

1272 def import_dbapi(cls) -> DBAPIModule: 

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

1274 

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

1276 instance variable to a constructed dialect under the name 

1277 ``.dbapi``. 

1278 

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

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

1281 which would be replaced at dialect instantiation time by the 

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

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

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

1285 

1286 """ 

1287 raise NotImplementedError() 

1288 

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

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

1291 

1292 Dialect classes will usually use the 

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

1294 accomplish this. 

1295 

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

1297 contain no dialect-instance state. 

1298 

1299 """ 

1300 

1301 raise NotImplementedError() 

1302 

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

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

1305 connection. 

1306 

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

1308 other properties. 

1309 

1310 The connection passed here is a SQLAlchemy Connection object, 

1311 with full capabilities. 

1312 

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

1314 super(). 

1315 

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

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

1318 

1319 """ 

1320 

1321 if TYPE_CHECKING: 

1322 

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

1324 

1325 def get_columns( 

1326 self, 

1327 connection: Connection, 

1328 table_name: str, 

1329 schema: Optional[str] = None, 

1330 **kw: Any, 

1331 ) -> List[ReflectedColumn]: 

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

1333 

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

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

1336 information as a list of dictionaries 

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

1338 

1339 This is an internal dialect method. Applications should use 

1340 :meth:`.Inspector.get_columns`. 

1341 

1342 """ 

1343 

1344 raise NotImplementedError() 

1345 

1346 def get_multi_columns( 

1347 self, 

1348 connection: Connection, 

1349 *, 

1350 schema: Optional[str] = None, 

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

1352 **kw: Any, 

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

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

1355 given ``schema``. 

1356 

1357 This is an internal dialect method. Applications should use 

1358 :meth:`.Inspector.get_multi_columns`. 

1359 

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

1361 implementation that will call the single table method for 

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

1363 :meth:`Dialect.get_view_names` or 

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

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

1366 implementation should implement this method. 

1367 

1368 .. versionadded:: 2.0 

1369 

1370 """ 

1371 

1372 raise NotImplementedError() 

1373 

1374 def get_pk_constraint( 

1375 self, 

1376 connection: Connection, 

1377 table_name: str, 

1378 schema: Optional[str] = None, 

1379 **kw: Any, 

1380 ) -> ReflectedPrimaryKeyConstraint: 

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

1382 table_name`. 

1383 

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

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

1386 key information as a dictionary corresponding to the 

1387 :class:`.ReflectedPrimaryKeyConstraint` dictionary. 

1388 

1389 This is an internal dialect method. Applications should use 

1390 :meth:`.Inspector.get_pk_constraint`. 

1391 

1392 """ 

1393 raise NotImplementedError() 

1394 

1395 def get_multi_pk_constraint( 

1396 self, 

1397 connection: Connection, 

1398 *, 

1399 schema: Optional[str] = None, 

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

1401 **kw: Any, 

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

1403 """Return information about primary key constraints in 

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

1405 

1406 This is an internal dialect method. Applications should use 

1407 :meth:`.Inspector.get_multi_pk_constraint`. 

1408 

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

1410 implementation that will call the single table method for 

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

1412 :meth:`Dialect.get_view_names` or 

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

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

1415 implementation should implement this method. 

1416 

1417 .. versionadded:: 2.0 

1418 

1419 """ 

1420 raise NotImplementedError() 

1421 

1422 def get_foreign_keys( 

1423 self, 

1424 connection: Connection, 

1425 table_name: str, 

1426 schema: Optional[str] = None, 

1427 **kw: Any, 

1428 ) -> List[ReflectedForeignKeyConstraint]: 

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

1430 

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

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

1433 key information as a list of dicts corresponding to the 

1434 :class:`.ReflectedForeignKeyConstraint` dictionary. 

1435 

1436 This is an internal dialect method. Applications should use 

1437 :meth:`_engine.Inspector.get_foreign_keys`. 

1438 """ 

1439 

1440 raise NotImplementedError() 

1441 

1442 def get_multi_foreign_keys( 

1443 self, 

1444 connection: Connection, 

1445 *, 

1446 schema: Optional[str] = None, 

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

1448 **kw: Any, 

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

1450 """Return information about foreign_keys in all tables 

1451 in the given ``schema``. 

1452 

1453 This is an internal dialect method. Applications should use 

1454 :meth:`_engine.Inspector.get_multi_foreign_keys`. 

1455 

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

1457 implementation that will call the single table method for 

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

1459 :meth:`Dialect.get_view_names` or 

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

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

1462 implementation should implement this method. 

1463 

1464 .. versionadded:: 2.0 

1465 

1466 """ 

1467 

1468 raise NotImplementedError() 

1469 

1470 def get_table_names( 

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

1472 ) -> List[str]: 

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

1474 

1475 This is an internal dialect method. Applications should use 

1476 :meth:`_engine.Inspector.get_table_names`. 

1477 

1478 """ 

1479 

1480 raise NotImplementedError() 

1481 

1482 def get_temp_table_names( 

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

1484 ) -> List[str]: 

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

1486 if supported by the underlying backend. 

1487 

1488 This is an internal dialect method. Applications should use 

1489 :meth:`_engine.Inspector.get_temp_table_names`. 

1490 

1491 """ 

1492 

1493 raise NotImplementedError() 

1494 

1495 def get_view_names( 

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

1497 ) -> List[str]: 

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

1499 database. 

1500 

1501 This is an internal dialect method. Applications should use 

1502 :meth:`_engine.Inspector.get_view_names`. 

1503 

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

1505 

1506 """ 

1507 

1508 raise NotImplementedError() 

1509 

1510 def get_materialized_view_names( 

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

1512 ) -> List[str]: 

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

1514 database. 

1515 

1516 This is an internal dialect method. Applications should use 

1517 :meth:`_engine.Inspector.get_materialized_view_names`. 

1518 

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

1520 

1521 .. versionadded:: 2.0 

1522 

1523 """ 

1524 

1525 raise NotImplementedError() 

1526 

1527 def get_sequence_names( 

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

1529 ) -> List[str]: 

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

1531 

1532 This is an internal dialect method. Applications should use 

1533 :meth:`_engine.Inspector.get_sequence_names`. 

1534 

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

1536 

1537 .. versionadded:: 1.4 

1538 """ 

1539 

1540 raise NotImplementedError() 

1541 

1542 def get_temp_view_names( 

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

1544 ) -> List[str]: 

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

1546 if supported by the underlying backend. 

1547 

1548 This is an internal dialect method. Applications should use 

1549 :meth:`_engine.Inspector.get_temp_view_names`. 

1550 

1551 """ 

1552 

1553 raise NotImplementedError() 

1554 

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

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

1557 

1558 This is an internal dialect method. Applications should use 

1559 :meth:`_engine.Inspector.get_schema_names`. 

1560 """ 

1561 raise NotImplementedError() 

1562 

1563 def get_view_definition( 

1564 self, 

1565 connection: Connection, 

1566 view_name: str, 

1567 schema: Optional[str] = None, 

1568 **kw: Any, 

1569 ) -> str: 

1570 """Return plain or materialized view definition. 

1571 

1572 This is an internal dialect method. Applications should use 

1573 :meth:`_engine.Inspector.get_view_definition`. 

1574 

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

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

1577 definition. 

1578 """ 

1579 

1580 raise NotImplementedError() 

1581 

1582 def get_indexes( 

1583 self, 

1584 connection: Connection, 

1585 table_name: str, 

1586 schema: Optional[str] = None, 

1587 **kw: Any, 

1588 ) -> List[ReflectedIndex]: 

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

1590 

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

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

1593 information as a list of dictionaries corresponding to the 

1594 :class:`.ReflectedIndex` dictionary. 

1595 

1596 This is an internal dialect method. Applications should use 

1597 :meth:`.Inspector.get_indexes`. 

1598 """ 

1599 

1600 raise NotImplementedError() 

1601 

1602 def get_multi_indexes( 

1603 self, 

1604 connection: Connection, 

1605 *, 

1606 schema: Optional[str] = None, 

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

1608 **kw: Any, 

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

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

1611 in the given ``schema``. 

1612 

1613 This is an internal dialect method. Applications should use 

1614 :meth:`.Inspector.get_multi_indexes`. 

1615 

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

1617 implementation that will call the single table method for 

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

1619 :meth:`Dialect.get_view_names` or 

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

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

1622 implementation should implement this method. 

1623 

1624 .. versionadded:: 2.0 

1625 

1626 """ 

1627 

1628 raise NotImplementedError() 

1629 

1630 def get_unique_constraints( 

1631 self, 

1632 connection: Connection, 

1633 table_name: str, 

1634 schema: Optional[str] = None, 

1635 **kw: Any, 

1636 ) -> List[ReflectedUniqueConstraint]: 

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

1638 

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

1640 unique constraint information as a list of dicts corresponding 

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

1642 

1643 This is an internal dialect method. Applications should use 

1644 :meth:`.Inspector.get_unique_constraints`. 

1645 """ 

1646 

1647 raise NotImplementedError() 

1648 

1649 def get_multi_unique_constraints( 

1650 self, 

1651 connection: Connection, 

1652 *, 

1653 schema: Optional[str] = None, 

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

1655 **kw: Any, 

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

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

1658 in the given ``schema``. 

1659 

1660 This is an internal dialect method. Applications should use 

1661 :meth:`.Inspector.get_multi_unique_constraints`. 

1662 

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

1664 implementation that will call the single table method for 

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

1666 :meth:`Dialect.get_view_names` or 

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

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

1669 implementation should implement this method. 

1670 

1671 .. versionadded:: 2.0 

1672 

1673 """ 

1674 

1675 raise NotImplementedError() 

1676 

1677 def get_check_constraints( 

1678 self, 

1679 connection: Connection, 

1680 table_name: str, 

1681 schema: Optional[str] = None, 

1682 **kw: Any, 

1683 ) -> List[ReflectedCheckConstraint]: 

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

1685 

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

1687 check constraint information as a list of dicts corresponding 

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

1689 

1690 This is an internal dialect method. Applications should use 

1691 :meth:`.Inspector.get_check_constraints`. 

1692 

1693 """ 

1694 

1695 raise NotImplementedError() 

1696 

1697 def get_multi_check_constraints( 

1698 self, 

1699 connection: Connection, 

1700 *, 

1701 schema: Optional[str] = None, 

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

1703 **kw: Any, 

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

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

1706 in the given ``schema``. 

1707 

1708 This is an internal dialect method. Applications should use 

1709 :meth:`.Inspector.get_multi_check_constraints`. 

1710 

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

1712 implementation that will call the single table method for 

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

1714 :meth:`Dialect.get_view_names` or 

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

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

1717 implementation should implement this method. 

1718 

1719 .. versionadded:: 2.0 

1720 

1721 """ 

1722 

1723 raise NotImplementedError() 

1724 

1725 def get_table_options( 

1726 self, 

1727 connection: Connection, 

1728 table_name: str, 

1729 schema: Optional[str] = None, 

1730 **kw: Any, 

1731 ) -> Dict[str, Any]: 

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

1733 was created. 

1734 

1735 This is an internal dialect method. Applications should use 

1736 :meth:`_engine.Inspector.get_table_options`. 

1737 """ 

1738 raise NotImplementedError() 

1739 

1740 def get_multi_table_options( 

1741 self, 

1742 connection: Connection, 

1743 *, 

1744 schema: Optional[str] = None, 

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

1746 **kw: Any, 

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

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

1749 given schema were created. 

1750 

1751 This is an internal dialect method. Applications should use 

1752 :meth:`_engine.Inspector.get_multi_table_options`. 

1753 

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

1755 implementation that will call the single table method for 

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

1757 :meth:`Dialect.get_view_names` or 

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

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

1760 implementation should implement this method. 

1761 

1762 .. versionadded:: 2.0 

1763 

1764 """ 

1765 raise NotImplementedError() 

1766 

1767 def get_table_comment( 

1768 self, 

1769 connection: Connection, 

1770 table_name: str, 

1771 schema: Optional[str] = None, 

1772 **kw: Any, 

1773 ) -> ReflectedTableComment: 

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

1775 

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

1777 table comment information as a dictionary corresponding to the 

1778 :class:`.ReflectedTableComment` dictionary. 

1779 

1780 This is an internal dialect method. Applications should use 

1781 :meth:`.Inspector.get_table_comment`. 

1782 

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

1784 comments. 

1785 

1786 """ 

1787 

1788 raise NotImplementedError() 

1789 

1790 def get_multi_table_comment( 

1791 self, 

1792 connection: Connection, 

1793 *, 

1794 schema: Optional[str] = None, 

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

1796 **kw: Any, 

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

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

1799 in the given ``schema``. 

1800 

1801 This is an internal dialect method. Applications should use 

1802 :meth:`_engine.Inspector.get_multi_table_comment`. 

1803 

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

1805 implementation that will call the single table method for 

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

1807 :meth:`Dialect.get_view_names` or 

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

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

1810 implementation should implement this method. 

1811 

1812 .. versionadded:: 2.0 

1813 

1814 """ 

1815 

1816 raise NotImplementedError() 

1817 

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

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

1820 case insensitive. 

1821 

1822 This method is only used if the dialect defines 

1823 requires_name_normalize=True. 

1824 

1825 """ 

1826 raise NotImplementedError() 

1827 

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

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

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

1831 

1832 This method is only used if the dialect defines 

1833 requires_name_normalize=True. 

1834 

1835 """ 

1836 raise NotImplementedError() 

1837 

1838 def has_table( 

1839 self, 

1840 connection: Connection, 

1841 table_name: str, 

1842 schema: Optional[str] = None, 

1843 **kw: Any, 

1844 ) -> bool: 

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

1846 or view in the database. 

1847 

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

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

1850 database, False otherwise. 

1851 

1852 This method serves as the underlying implementation of the 

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

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

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

1856 

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

1858 published so that third-party dialects may provide an 

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

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

1861 

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

1863 formally supports checking for additional table-like objects: 

1864 

1865 * any type of views (plain or materialized) 

1866 * temporary tables of any kind 

1867 

1868 Previously, these two checks were not formally specified and 

1869 different dialects would vary in their behavior. The dialect 

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

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

1872 or temporary tables should seek to support locating these objects 

1873 for full compliance. 

1874 

1875 """ 

1876 

1877 raise NotImplementedError() 

1878 

1879 def has_index( 

1880 self, 

1881 connection: Connection, 

1882 table_name: str, 

1883 index_name: str, 

1884 schema: Optional[str] = None, 

1885 **kw: Any, 

1886 ) -> bool: 

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

1888 

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

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

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

1892 

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

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

1895 however dialects can implement a more performant version. 

1896 

1897 This is an internal dialect method. Applications should use 

1898 :meth:`_engine.Inspector.has_index`. 

1899 

1900 .. versionadded:: 1.4 

1901 

1902 """ 

1903 

1904 raise NotImplementedError() 

1905 

1906 def has_sequence( 

1907 self, 

1908 connection: Connection, 

1909 sequence_name: str, 

1910 schema: Optional[str] = None, 

1911 **kw: Any, 

1912 ) -> bool: 

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

1914 

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

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

1917 the database, ``False`` otherwise. 

1918 

1919 This is an internal dialect method. Applications should use 

1920 :meth:`_engine.Inspector.has_sequence`. 

1921 """ 

1922 

1923 raise NotImplementedError() 

1924 

1925 def has_schema( 

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

1927 ) -> bool: 

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

1929 

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

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

1932 given exists, ``False`` otherwise. 

1933 

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

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

1936 :meth:`.Dialect.get_schema_names`, 

1937 however dialects can implement a more performant version. 

1938 

1939 This is an internal dialect method. Applications should use 

1940 :meth:`_engine.Inspector.has_schema`. 

1941 

1942 .. versionadded:: 2.0 

1943 

1944 """ 

1945 

1946 raise NotImplementedError() 

1947 

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

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

1950 

1951 This is used by the default implementation to populate the 

1952 "server_version_info" attribute and is called exactly 

1953 once upon first connect. 

1954 

1955 """ 

1956 

1957 raise NotImplementedError() 

1958 

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

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

1961 the given connection. 

1962 

1963 This is used by the default implementation to populate the 

1964 "default_schema_name" attribute and is called exactly 

1965 once upon first connect. 

1966 

1967 """ 

1968 

1969 raise NotImplementedError() 

1970 

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

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

1973 DB-API connection. 

1974 

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

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

1977 DBAPIs that might need additional help in this area. 

1978 

1979 :param dbapi_connection: a DBAPI connection, typically 

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

1981 

1982 """ 

1983 

1984 raise NotImplementedError() 

1985 

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

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

1988 a DB-API connection. 

1989 

1990 :param dbapi_connection: a DBAPI connection, typically 

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

1992 

1993 """ 

1994 

1995 raise NotImplementedError() 

1996 

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

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

1999 DB-API connection. 

2000 

2001 :param dbapi_connection: a DBAPI connection, typically 

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

2003 

2004 """ 

2005 

2006 raise NotImplementedError() 

2007 

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

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

2010 much as possible to not block, given a DBAPI 

2011 connection. 

2012 

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

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

2015 

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

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

2018 

2019 .. versionadded:: 1.4.41 

2020 

2021 """ 

2022 

2023 raise NotImplementedError() 

2024 

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

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

2027 connection. 

2028 

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

2030 when a connection has been 

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

2032 capacity of the pool. 

2033 

2034 """ 

2035 

2036 raise NotImplementedError() 

2037 

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

2039 raise NotImplementedError() 

2040 

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

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

2043 usable.""" 

2044 raise NotImplementedError() 

2045 

2046 def do_set_input_sizes( 

2047 self, 

2048 cursor: DBAPICursor, 

2049 list_of_tuples: _GenericSetInputSizesType, 

2050 context: ExecutionContext, 

2051 ) -> Any: 

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

2053 

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

2055 set to the 

2056 :attr:`.BindTyping.SETINPUTSIZES` value. 

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

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

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

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

2061 

2062 .. versionadded:: 1.4 

2063 

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

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

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

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

2068 appropriately. 

2069 

2070 

2071 """ 

2072 raise NotImplementedError() 

2073 

2074 def create_xid(self) -> Any: 

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

2076 

2077 This id will be passed to do_begin_twophase(), 

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

2079 unspecified. 

2080 """ 

2081 

2082 raise NotImplementedError() 

2083 

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

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

2086 

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

2088 :param name: savepoint name. 

2089 

2090 """ 

2091 

2092 raise NotImplementedError() 

2093 

2094 def do_rollback_to_savepoint( 

2095 self, connection: Connection, name: str 

2096 ) -> None: 

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

2098 

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

2100 :param name: savepoint name. 

2101 

2102 """ 

2103 

2104 raise NotImplementedError() 

2105 

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

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

2108 

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

2110 :param name: savepoint name. 

2111 """ 

2112 

2113 raise NotImplementedError() 

2114 

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

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

2117 

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

2119 :param xid: xid 

2120 

2121 """ 

2122 

2123 raise NotImplementedError() 

2124 

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

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

2127 

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

2129 :param xid: xid 

2130 

2131 """ 

2132 

2133 raise NotImplementedError() 

2134 

2135 def do_rollback_twophase( 

2136 self, 

2137 connection: Connection, 

2138 xid: Any, 

2139 is_prepared: bool = True, 

2140 recover: bool = False, 

2141 ) -> None: 

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

2143 

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

2145 :param xid: xid 

2146 :param is_prepared: whether or not 

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

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

2149 

2150 """ 

2151 

2152 raise NotImplementedError() 

2153 

2154 def do_commit_twophase( 

2155 self, 

2156 connection: Connection, 

2157 xid: Any, 

2158 is_prepared: bool = True, 

2159 recover: bool = False, 

2160 ) -> None: 

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

2162 

2163 

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

2165 :param xid: xid 

2166 :param is_prepared: whether or not 

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

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

2169 

2170 """ 

2171 

2172 raise NotImplementedError() 

2173 

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

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

2176 identifiers on the given connection. 

2177 

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

2179 

2180 """ 

2181 

2182 raise NotImplementedError() 

2183 

2184 def _deliver_insertmanyvalues_batches( 

2185 self, 

2186 connection: Connection, 

2187 cursor: DBAPICursor, 

2188 statement: str, 

2189 parameters: _DBAPIMultiExecuteParams, 

2190 generic_setinputsizes: Optional[_GenericSetInputSizesType], 

2191 context: ExecutionContext, 

2192 ) -> Iterator[_InsertManyValuesBatch]: 

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

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

2195 feature. 

2196 

2197 """ 

2198 raise NotImplementedError() 

2199 

2200 def do_executemany( 

2201 self, 

2202 cursor: DBAPICursor, 

2203 statement: str, 

2204 parameters: _DBAPIMultiExecuteParams, 

2205 context: Optional[ExecutionContext] = None, 

2206 ) -> None: 

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

2208 parameters)``.""" 

2209 

2210 raise NotImplementedError() 

2211 

2212 def do_execute( 

2213 self, 

2214 cursor: DBAPICursor, 

2215 statement: str, 

2216 parameters: Optional[_DBAPISingleExecuteParams], 

2217 context: Optional[ExecutionContext] = None, 

2218 ) -> None: 

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

2220 parameters)``.""" 

2221 

2222 raise NotImplementedError() 

2223 

2224 def do_execute_no_params( 

2225 self, 

2226 cursor: DBAPICursor, 

2227 statement: str, 

2228 context: Optional[ExecutionContext] = None, 

2229 ) -> None: 

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

2231 

2232 The parameter collection should not be sent. 

2233 

2234 """ 

2235 

2236 raise NotImplementedError() 

2237 

2238 def is_disconnect( 

2239 self, 

2240 e: DBAPIModule.Error, 

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

2242 cursor: Optional[DBAPICursor], 

2243 ) -> bool: 

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

2245 connection""" 

2246 

2247 raise NotImplementedError() 

2248 

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

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

2251 

2252 The default implementation of this method is:: 

2253 

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

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

2256 

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

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

2259 

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

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

2262 DBAPI. 

2263 

2264 

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

2266 :meth:`.Dialect.create_connect_args` method 

2267 

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

2269 :meth:`.Dialect.create_connect_args` method. 

2270 

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

2272 level ``.connect()`` function. 

2273 

2274 .. seealso:: 

2275 

2276 :meth:`.Dialect.create_connect_args` 

2277 

2278 :meth:`.Dialect.on_connect` 

2279 

2280 """ 

2281 raise NotImplementedError() 

2282 

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

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

2285 

2286 This method is a new hook that supersedes the 

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

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

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

2290 compatibility with existing dialects. There is no deprecation 

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

2292 

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

2294 DBAPI connection itself. The inner callable has no 

2295 return value. 

2296 

2297 E.g.:: 

2298 

2299 class MyDialect(default.DefaultDialect): 

2300 # ... 

2301 

2302 def on_connect_url(self, url): 

2303 def do_on_connect(connection): 

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

2305 

2306 return do_on_connect 

2307 

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

2309 isolation modes, Unicode modes, etc. 

2310 

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

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

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

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

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

2316 replaced by plugins. 

2317 

2318 .. note:: 

2319 

2320 The default implementation of 

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

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

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

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

2325 it directly from here. 

2326 

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

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

2329 

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

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

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

2333 

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

2335 argument, or None. 

2336 

2337 .. seealso:: 

2338 

2339 :meth:`_engine.Dialect.on_connect` 

2340 

2341 """ 

2342 return self.on_connect() 

2343 

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

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

2346 

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

2348 DBAPI connection itself. The inner callable has no 

2349 return value. 

2350 

2351 E.g.:: 

2352 

2353 class MyDialect(default.DefaultDialect): 

2354 # ... 

2355 

2356 def on_connect(self): 

2357 def do_on_connect(connection): 

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

2359 

2360 return do_on_connect 

2361 

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

2363 isolation modes, Unicode modes, etc. 

2364 

2365 The "do_on_connect" callable is invoked by using the 

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

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

2368 callable. 

2369 

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

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

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

2373 

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

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

2376 the connect args. Dialects can implement on_connect_url instead 

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

2378 connection in order to get additional context. 

2379 

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

2381 

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

2383 argument, or None. 

2384 

2385 .. seealso:: 

2386 

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

2388 itself to be controlled. 

2389 

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

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

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

2393 

2394 """ 

2395 return None 

2396 

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

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

2399 

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

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

2402 :class:`_engine.Engine` 

2403 isolation level facilities; these APIs should be preferred for 

2404 most typical use cases. 

2405 

2406 .. seealso:: 

2407 

2408 :meth:`_engine.Connection.get_isolation_level` 

2409 - view current level 

2410 

2411 :attr:`_engine.Connection.default_isolation_level` 

2412 - view default level 

2413 

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

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

2416 

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

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

2419 

2420 """ 

2421 

2422 raise NotImplementedError() 

2423 

2424 def set_isolation_level( 

2425 self, dbapi_connection: DBAPIConnection, level: IsolationLevel 

2426 ) -> None: 

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

2428 

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

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

2431 :class:`_engine.Engine` 

2432 isolation level facilities; these APIs should be preferred for 

2433 most typical use cases. 

2434 

2435 If the dialect also implements the 

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

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

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

2439 

2440 .. seealso:: 

2441 

2442 :meth:`_engine.Connection.get_isolation_level` 

2443 - view current level 

2444 

2445 :attr:`_engine.Connection.default_isolation_level` 

2446 - view default level 

2447 

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

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

2450 

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

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

2453 

2454 """ 

2455 

2456 raise NotImplementedError() 

2457 

2458 def get_isolation_level( 

2459 self, dbapi_connection: DBAPIConnection 

2460 ) -> IsolationLevel: 

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

2462 

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

2464 the corresponding 

2465 DBAPI connection may be procured using the 

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

2467 

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

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

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

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

2472 

2473 

2474 .. seealso:: 

2475 

2476 :meth:`_engine.Connection.get_isolation_level` 

2477 - view current level 

2478 

2479 :attr:`_engine.Connection.default_isolation_level` 

2480 - view default level 

2481 

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

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

2484 

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

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

2487 

2488 

2489 """ 

2490 

2491 raise NotImplementedError() 

2492 

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

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

2495 

2496 :param dbapi_connection: a DBAPI connection object 

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

2498 :rtype: bool 

2499 

2500 This method inspects the given DBAPI connection to determine 

2501 whether autocommit mode is currently enabled. The specific 

2502 mechanism for detecting autocommit varies by database dialect 

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

2504 round trips. 

2505 

2506 .. note:: 

2507 

2508 Not all dialects support autocommit detection. Dialects 

2509 that do not support this feature will raise 

2510 :exc:`NotImplementedError`. 

2511 

2512 """ 

2513 raise NotImplementedError( 

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

2515 ) 

2516 

2517 def get_default_isolation_level( 

2518 self, dbapi_conn: DBAPIConnection 

2519 ) -> IsolationLevel: 

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

2521 a default isolation level if one cannot be retrieved. 

2522 

2523 This method may only raise NotImplementedError and 

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

2525 first connect. 

2526 

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

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

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

2530 

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

2532 method unless overridden by a dialect. 

2533 

2534 """ 

2535 raise NotImplementedError() 

2536 

2537 def get_isolation_level_values( 

2538 self, dbapi_conn: DBAPIConnection 

2539 ) -> Sequence[IsolationLevel]: 

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

2541 by this dialect. 

2542 

2543 The available names should use the following conventions: 

2544 

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

2546 names but these are normalized into UPPERCASE before being passed 

2547 along to the dialect. 

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

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

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

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

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

2553 ``READ COMMITTED``, ``REPEATABLE READ``, ``SERIALIZABLE`` 

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

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

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

2557 are named in UPPERCASE and use spaces not underscores. 

2558 

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

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

2561 :class:`_exc.ArgumentError`. 

2562 

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

2564 the dialect needs to interrogate the connection itself to determine 

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

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

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

2568 

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

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

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

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

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

2574 not yet be implementing this method. 

2575 

2576 .. versionadded:: 2.0 

2577 

2578 """ 

2579 raise NotImplementedError() 

2580 

2581 def _assert_and_set_isolation_level( 

2582 self, dbapi_conn: DBAPIConnection, level: IsolationLevel 

2583 ) -> None: 

2584 raise NotImplementedError() 

2585 

2586 @classmethod 

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

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

2589 

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

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

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

2593 the actual dialect to be used. 

2594 

2595 By default this just returns the cls. 

2596 

2597 """ 

2598 return cls 

2599 

2600 @classmethod 

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

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

2603 an async engine. 

2604 

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

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

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

2608 ``psycopg`` driver. 

2609 

2610 .. versionadded:: 2 

2611 

2612 .. seealso:: 

2613 

2614 :meth:`.Dialect.get_dialect_cls` 

2615 

2616 """ 

2617 return cls.get_dialect_cls(url) 

2618 

2619 @classmethod 

2620 def load_provisioning(cls) -> None: 

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

2622 

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

2624 provisioning followers, this method should initiate that process. 

2625 

2626 A typical implementation would be:: 

2627 

2628 @classmethod 

2629 def load_provisioning(cls): 

2630 __import__("mydialect.provision") 

2631 

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

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

2634 attribute:: 

2635 

2636 @classmethod 

2637 def load_provisioning(cls): 

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

2639 try: 

2640 __import__(package + ".provision") 

2641 except ImportError: 

2642 pass 

2643 

2644 """ 

2645 

2646 @classmethod 

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

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

2649 :class:`_engine.Engine`. 

2650 

2651 If the dialect returned a different class from the 

2652 :meth:`.get_dialect_cls` 

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

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

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

2656 

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

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

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

2660 

2661 """ 

2662 

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

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

2665 package. 

2666 

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

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

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

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

2671 connection-like object as returned by the driver. 

2672 

2673 .. versionadded:: 1.4.24 

2674 

2675 """ 

2676 raise NotImplementedError() 

2677 

2678 def set_engine_execution_options( 

2679 self, engine: Engine, opts: CoreExecuteOptionsParameter 

2680 ) -> None: 

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

2682 

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

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

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

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

2687 connection. 

2688 

2689 """ 

2690 raise NotImplementedError() 

2691 

2692 def set_connection_execution_options( 

2693 self, connection: Connection, opts: CoreExecuteOptionsParameter 

2694 ) -> None: 

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

2696 

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

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

2699 execution option. Dialects can intercept various execution options 

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

2701 

2702 .. versionadded:: 1.4 

2703 

2704 """ 

2705 raise NotImplementedError() 

2706 

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

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

2709 raise NotImplementedError() 

2710 

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

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

2713 

2714 

2715class CreateEnginePlugin: 

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

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

2718 

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

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

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

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

2723 :class:`_engine.CreateEnginePlugin` include: 

2724 

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

2726 number of checkouts and/or time spent with statements 

2727 

2728 * connectivity plugins such as proxies 

2729 

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

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

2732 

2733 

2734 import logging 

2735 

2736 from sqlalchemy.engine import CreateEnginePlugin 

2737 from sqlalchemy import event 

2738 

2739 

2740 class LogCursorEventsPlugin(CreateEnginePlugin): 

2741 def __init__(self, url, kwargs): 

2742 # consume the parameter "log_cursor_logging_name" from the 

2743 # URL query 

2744 logging_name = url.query.get( 

2745 "log_cursor_logging_name", "log_cursor" 

2746 ) 

2747 

2748 self.log = logging.getLogger(logging_name) 

2749 

2750 def update_url(self, url): 

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

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

2753 

2754 def engine_created(self, engine): 

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

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

2757 

2758 def _log_event( 

2759 self, 

2760 conn, 

2761 cursor, 

2762 statement, 

2763 parameters, 

2764 context, 

2765 executemany, 

2766 ): 

2767 

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

2769 

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

2771 of dialects:: 

2772 

2773 entry_points = { 

2774 "sqlalchemy.plugins": [ 

2775 "log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin" 

2776 ] 

2777 } 

2778 

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

2780 URL as in:: 

2781 

2782 from sqlalchemy import create_engine 

2783 

2784 engine = create_engine( 

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

2786 "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger" 

2787 ) 

2788 

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

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

2791 in the URL:: 

2792 

2793 engine = create_engine( 

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

2795 "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three" 

2796 ) 

2797 

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

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

2800 

2801 engine = create_engine( 

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

2803 ) 

2804 

2805 A plugin may consume plugin-specific arguments from the 

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

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

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

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

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

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

2812 

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

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

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

2816 should be consumed by implementing the 

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

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

2819 

2820 class MyPlugin(CreateEnginePlugin): 

2821 def __init__(self, url, kwargs): 

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

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

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

2825 

2826 def update_url(self, url): 

2827 return url.difference_update_query( 

2828 ["my_argument_one", "my_argument_two"] 

2829 ) 

2830 

2831 Arguments like those illustrated above would be consumed from a 

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

2833 

2834 from sqlalchemy import create_engine 

2835 

2836 engine = create_engine( 

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

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

2839 my_argument_three="bat", 

2840 ) 

2841 

2842 .. versionchanged:: 1.4 

2843 

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

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

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

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

2848 is invoked after the plugin is constructed. 

2849 

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

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

2852 method to detect which version is running:: 

2853 

2854 class MyPlugin(CreateEnginePlugin): 

2855 def __init__(self, url, kwargs): 

2856 if hasattr(CreateEnginePlugin, "update_url"): 

2857 # detect the 1.4 API 

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

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

2860 else: 

2861 # detect the 1.3 and earlier API - mutate the 

2862 # URL directly 

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

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

2865 

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

2867 

2868 def update_url(self, url): 

2869 # this method is only called in the 1.4 version 

2870 return url.difference_update_query( 

2871 ["my_argument_one", "my_argument_two"] 

2872 ) 

2873 

2874 .. seealso:: 

2875 

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

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

2878 

2879 

2880 When the engine creation process completes and produces the 

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

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

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

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

2885 

2886 """ # noqa: E501 

2887 

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

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

2890 

2891 The plugin object is instantiated individually for each call 

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

2893 Engine` will be 

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

2895 corresponding to this URL. 

2896 

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

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

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

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

2901 

2902 .. versionchanged:: 1.4 

2903 

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

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

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

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

2908 

2909 :param kwargs: The keyword arguments passed to 

2910 :func:`_sa.create_engine`. 

2911 

2912 """ 

2913 self.url = url 

2914 

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

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

2917 

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

2919 typically used to consume configuration arguments from the 

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

2921 recognized by the dialect. The 

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

2923 to remove these arguments. See the docstring at 

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

2925 

2926 

2927 .. versionadded:: 1.4 

2928 

2929 """ 

2930 raise NotImplementedError() 

2931 

2932 def handle_dialect_kwargs( 

2933 self, dialect_cls: Type[Dialect], dialect_args: Dict[str, Any] 

2934 ) -> None: 

2935 """parse and modify dialect kwargs""" 

2936 

2937 def handle_pool_kwargs( 

2938 self, pool_cls: Type[Pool], pool_args: Dict[str, Any] 

2939 ) -> None: 

2940 """parse and modify pool kwargs""" 

2941 

2942 def engine_created(self, engine: Engine) -> None: 

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

2944 object when it is fully constructed. 

2945 

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

2947 registering engine or connection pool events. 

2948 

2949 """ 

2950 

2951 

2952class ExecutionContext: 

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

2954 execution. 

2955 

2956 """ 

2957 

2958 engine: Engine 

2959 """engine which the Connection is associated with""" 

2960 

2961 connection: Connection 

2962 """Connection object which can be freely used by default value 

2963 generators to execute SQL. This Connection should reference the 

2964 same underlying connection/transactional resources of 

2965 root_connection.""" 

2966 

2967 root_connection: Connection 

2968 """Connection object which is the source of this ExecutionContext.""" 

2969 

2970 dialect: Dialect 

2971 """dialect which created this ExecutionContext.""" 

2972 

2973 cursor: DBAPICursor 

2974 """DB-API cursor procured from the connection""" 

2975 

2976 compiled: Optional[Compiled] 

2977 """if passed to constructor, sqlalchemy.engine.base.Compiled object 

2978 being executed""" 

2979 

2980 statement: str 

2981 """string version of the statement to be executed. Is either 

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

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

2984 

2985 invoked_statement: Optional[Executable] 

2986 """The Executable statement object that was given in the first place. 

2987 

2988 This should be structurally equivalent to compiled.statement, but not 

2989 necessarily the same object as in a caching scenario the compiled form 

2990 will have been extracted from the cache. 

2991 

2992 """ 

2993 

2994 parameters: _AnyMultiExecuteParams 

2995 """bind parameters passed to the execute() or exec_driver_sql() methods. 

2996 

2997 These are always stored as a list of parameter entries. A single-element 

2998 list corresponds to a ``cursor.execute()`` call and a multiple-element 

2999 list corresponds to ``cursor.executemany()``, except in the case 

3000 of :attr:`.ExecuteStyle.INSERTMANYVALUES` which will use 

3001 ``cursor.execute()`` one or more times. 

3002 

3003 """ 

3004 

3005 no_parameters: bool 

3006 """True if the execution style does not use parameters""" 

3007 

3008 isinsert: bool 

3009 """True if the statement is an INSERT.""" 

3010 

3011 isupdate: bool 

3012 """True if the statement is an UPDATE.""" 

3013 

3014 execute_style: ExecuteStyle 

3015 """the style of DBAPI cursor method that will be used to execute 

3016 a statement. 

3017 

3018 .. versionadded:: 2.0 

3019 

3020 """ 

3021 

3022 executemany: bool 

3023 """True if the context has a list of more than one parameter set. 

3024 

3025 Historically this attribute links to whether ``cursor.execute()`` or 

3026 ``cursor.executemany()`` will be used. It also can now mean that 

3027 "insertmanyvalues" may be used which indicates one or more 

3028 ``cursor.execute()`` calls. 

3029 

3030 """ 

3031 

3032 prefetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 

3033 """a list of Column objects for which a client-side default 

3034 was fired off. Applies to inserts and updates.""" 

3035 

3036 postfetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 

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

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

3039 and updates.""" 

3040 

3041 execution_options: _ExecuteOptions 

3042 """Execution options associated with the current statement execution""" 

3043 

3044 @classmethod 

3045 def _init_ddl( 

3046 cls, 

3047 dialect: Dialect, 

3048 connection: Connection, 

3049 dbapi_connection: PoolProxiedConnection, 

3050 execution_options: _ExecuteOptions, 

3051 compiled_ddl: DDLCompiler, 

3052 ) -> ExecutionContext: 

3053 raise NotImplementedError() 

3054 

3055 @classmethod 

3056 def _init_compiled( 

3057 cls, 

3058 dialect: Dialect, 

3059 connection: Connection, 

3060 dbapi_connection: PoolProxiedConnection, 

3061 execution_options: _ExecuteOptions, 

3062 compiled: SQLCompiler, 

3063 parameters: _CoreMultiExecuteParams, 

3064 invoked_statement: Executable, 

3065 extracted_parameters: Optional[Sequence[BindParameter[Any]]], 

3066 cache_hit: CacheStats = CacheStats.CACHING_DISABLED, 

3067 ) -> ExecutionContext: 

3068 raise NotImplementedError() 

3069 

3070 @classmethod 

3071 def _init_statement( 

3072 cls, 

3073 dialect: Dialect, 

3074 connection: Connection, 

3075 dbapi_connection: PoolProxiedConnection, 

3076 execution_options: _ExecuteOptions, 

3077 statement: str, 

3078 parameters: _DBAPIMultiExecuteParams, 

3079 ) -> ExecutionContext: 

3080 raise NotImplementedError() 

3081 

3082 @classmethod 

3083 def _init_default( 

3084 cls, 

3085 dialect: Dialect, 

3086 connection: Connection, 

3087 dbapi_connection: PoolProxiedConnection, 

3088 execution_options: _ExecuteOptions, 

3089 ) -> ExecutionContext: 

3090 raise NotImplementedError() 

3091 

3092 def _exec_default( 

3093 self, 

3094 column: Optional[Column[Any]], 

3095 default: DefaultGenerator, 

3096 type_: Optional[TypeEngine[Any]], 

3097 ) -> Any: 

3098 raise NotImplementedError() 

3099 

3100 def _prepare_set_input_sizes( 

3101 self, 

3102 ) -> Optional[List[Tuple[str, Any, TypeEngine[Any]]]]: 

3103 raise NotImplementedError() 

3104 

3105 def _get_cache_stats(self) -> str: 

3106 raise NotImplementedError() 

3107 

3108 def _setup_result_proxy(self) -> CursorResult[Any]: 

3109 raise NotImplementedError() 

3110 

3111 def fire_sequence(self, seq: Sequence_SchemaItem, type_: Integer) -> int: 

3112 """given a :class:`.Sequence`, invoke it and return the next int 

3113 value""" 

3114 raise NotImplementedError() 

3115 

3116 def create_cursor(self) -> DBAPICursor: 

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

3118 connection. 

3119 

3120 Some dialects may wish to change the behavior of 

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

3122 "server side" cursor. 

3123 """ 

3124 

3125 raise NotImplementedError() 

3126 

3127 def pre_exec(self) -> None: 

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

3129 

3130 If a compiled statement was passed to this ExecutionContext, 

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

3132 initialized after this statement is complete. 

3133 """ 

3134 

3135 raise NotImplementedError() 

3136 

3137 def get_out_parameter_values( 

3138 self, out_param_names: Sequence[str] 

3139 ) -> Sequence[Any]: 

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

3141 

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

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

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

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

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

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

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

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

3150 should set this flag explicitly. 

3151 

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

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

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

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

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

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

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

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

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

3161 transition. 

3162 

3163 .. versionadded:: 1.4 - added 

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

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

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

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

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

3169 

3170 """ 

3171 raise NotImplementedError() 

3172 

3173 def post_exec(self) -> None: 

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

3175 

3176 If a compiled statement was passed to this ExecutionContext, 

3177 the `last_insert_ids`, `last_inserted_params`, etc. 

3178 datamembers should be available after this method completes. 

3179 """ 

3180 

3181 raise NotImplementedError() 

3182 

3183 def handle_dbapi_exception(self, e: BaseException) -> None: 

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

3185 fetch, etc.""" 

3186 

3187 raise NotImplementedError() 

3188 

3189 def lastrow_has_defaults(self) -> bool: 

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

3191 inlined or database-side defaults. 

3192 """ 

3193 

3194 raise NotImplementedError() 

3195 

3196 def get_rowcount(self) -> Optional[int]: 

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

3198 cases an interpreted value. 

3199 

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

3201 

3202 """ 

3203 

3204 raise NotImplementedError() 

3205 

3206 def fetchall_for_returning(self, cursor: DBAPICursor) -> Sequence[Any]: 

3207 """For a RETURNING result, deliver cursor.fetchall() from the 

3208 DBAPI cursor. 

3209 

3210 This is a dialect-specific hook for dialects that have special 

3211 considerations when calling upon the rows delivered for a 

3212 "RETURNING" statement. Default implementation is 

3213 ``cursor.fetchall()``. 

3214 

3215 This hook is currently used only by the :term:`insertmanyvalues` 

3216 feature. Dialects that don't set ``use_insertmanyvalues=True`` 

3217 don't need to consider this hook. 

3218 

3219 .. versionadded:: 2.0.10 

3220 

3221 """ 

3222 raise NotImplementedError() 

3223 

3224 

3225class ConnectionEventsTarget(EventTarget): 

3226 """An object which can accept events from :class:`.ConnectionEvents`. 

3227 

3228 Includes :class:`_engine.Connection` and :class:`_engine.Engine`. 

3229 

3230 .. versionadded:: 2.0 

3231 

3232 """ 

3233 

3234 dispatch: dispatcher[ConnectionEventsTarget] 

3235 

3236 

3237Connectable = ConnectionEventsTarget 

3238 

3239 

3240class ExceptionContext: 

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

3242 

3243 This object exists solely to be passed to the 

3244 :meth:`_events.DialectEvents.handle_error` event, 

3245 supporting an interface that 

3246 can be extended without backwards-incompatibility. 

3247 

3248 

3249 """ 

3250 

3251 __slots__ = () 

3252 

3253 dialect: Dialect 

3254 """The :class:`_engine.Dialect` in use. 

3255 

3256 This member is present for all invocations of the event hook. 

3257 

3258 .. versionadded:: 2.0 

3259 

3260 """ 

3261 

3262 connection: Optional[Connection] 

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

3264 

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

3266 first connecting. 

3267 

3268 .. seealso:: 

3269 

3270 :attr:`.ExceptionContext.engine` 

3271 

3272 

3273 """ 

3274 

3275 engine: Optional[Engine] 

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

3277 

3278 This member is present in all cases except for when handling an error 

3279 within the connection pool "pre-ping" process. 

3280 

3281 """ 

3282 

3283 cursor: Optional[DBAPICursor] 

3284 """The DBAPI cursor object. 

3285 

3286 May be None. 

3287 

3288 """ 

3289 

3290 statement: Optional[str] 

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

3292 

3293 May be None. 

3294 

3295 """ 

3296 

3297 parameters: Optional[_DBAPIAnyExecuteParams] 

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

3299 

3300 May be None. 

3301 

3302 """ 

3303 

3304 original_exception: BaseException 

3305 """The exception object which was caught. 

3306 

3307 This member is always present. 

3308 

3309 """ 

3310 

3311 sqlalchemy_exception: Optional[StatementError] 

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

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

3314 

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

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

3317 field will always be present. 

3318 

3319 """ 

3320 

3321 chained_exception: Optional[BaseException] 

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

3323 exception chain, if any. 

3324 

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

3326 SQLAlchemy unless a subsequent handler replaces it. 

3327 

3328 May be None. 

3329 

3330 """ 

3331 

3332 execution_context: Optional[ExecutionContext] 

3333 """The :class:`.ExecutionContext` corresponding to the execution 

3334 operation in progress. 

3335 

3336 This is present for statement execution operations, but not for 

3337 operations such as transaction begin/end. It also is not present when 

3338 the exception was raised before the :class:`.ExecutionContext` 

3339 could be constructed. 

3340 

3341 Note that the :attr:`.ExceptionContext.statement` and 

3342 :attr:`.ExceptionContext.parameters` members may represent a 

3343 different value than that of the :class:`.ExecutionContext`, 

3344 potentially in the case where a 

3345 :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar 

3346 modified the statement/parameters to be sent. 

3347 

3348 May be None. 

3349 

3350 """ 

3351 

3352 is_disconnect: bool 

3353 """Represent whether the exception as occurred represents a "disconnect" 

3354 condition. 

3355 

3356 This flag will always be True or False within the scope of the 

3357 :meth:`_events.DialectEvents.handle_error` handler. 

3358 

3359 SQLAlchemy will defer to this flag in order to determine whether or not 

3360 the connection should be invalidated subsequently. That is, by 

3361 assigning to this flag, a "disconnect" event which then results in 

3362 a connection and pool invalidation can be invoked or prevented by 

3363 changing this flag. 

3364 

3365 

3366 .. note:: The pool "pre_ping" handler enabled using the 

3367 :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not** 

3368 consult this event before deciding if the "ping" returned false, 

3369 as opposed to receiving an unhandled error. For this use case, the 

3370 :ref:`legacy recipe based on engine_connect() may be used 

3371 <pool_disconnects_pessimistic_custom>`. A future API allow more 

3372 comprehensive customization of the "disconnect" detection mechanism 

3373 across all functions. 

3374 

3375 """ 

3376 

3377 invalidate_pool_on_disconnect: bool 

3378 """Represent whether all connections in the pool should be invalidated 

3379 when a "disconnect" condition is in effect. 

3380 

3381 Setting this flag to False within the scope of the 

3382 :meth:`_events.DialectEvents.handle_error` 

3383 event will have the effect such 

3384 that the full collection of connections in the pool will not be 

3385 invalidated during a disconnect; only the current connection that is the 

3386 subject of the error will actually be invalidated. 

3387 

3388 The purpose of this flag is for custom disconnect-handling schemes where 

3389 the invalidation of other connections in the pool is to be performed 

3390 based on other conditions, or even on a per-connection basis. 

3391 

3392 """ 

3393 

3394 is_pre_ping: bool 

3395 """Indicates if this error is occurring within the "pre-ping" step 

3396 performed when :paramref:`_sa.create_engine.pool_pre_ping` is set to 

3397 ``True``. In this mode, the :attr:`.ExceptionContext.engine` attribute 

3398 will be ``None``. The dialect in use is accessible via the 

3399 :attr:`.ExceptionContext.dialect` attribute. 

3400 

3401 .. versionadded:: 2.0.5 

3402 

3403 """ 

3404 

3405 

3406class AdaptedConnection: 

3407 """Interface of an adapted connection object to support the DBAPI protocol. 

3408 

3409 Used by asyncio dialects to provide a sync-style pep-249 facade on top 

3410 of the asyncio connection/cursor API provided by the driver. 

3411 

3412 .. versionadded:: 1.4.24 

3413 

3414 """ 

3415 

3416 __slots__ = ("_connection",) 

3417 

3418 _connection: AsyncIODBAPIConnection 

3419 

3420 @property 

3421 def driver_connection(self) -> Any: 

3422 """The connection object as returned by the driver after a connect.""" 

3423 return self._connection 

3424 

3425 def run_async(self, fn: Callable[[Any], Awaitable[_T]]) -> _T: 

3426 """Run the awaitable returned by the given function, which is passed 

3427 the raw asyncio driver connection. 

3428 

3429 This is used to invoke awaitable-only methods on the driver connection 

3430 within the context of a "synchronous" method, like a connection 

3431 pool event handler. 

3432 

3433 E.g.:: 

3434 

3435 engine = create_async_engine(...) 

3436 

3437 

3438 @event.listens_for(engine.sync_engine, "connect") 

3439 def register_custom_types( 

3440 dbapi_connection, # ... 

3441 ): 

3442 dbapi_connection.run_async( 

3443 lambda connection: connection.set_type_codec( 

3444 "MyCustomType", encoder, decoder, ... 

3445 ) 

3446 ) 

3447 

3448 .. versionadded:: 1.4.30 

3449 

3450 .. seealso:: 

3451 

3452 :ref:`asyncio_events_run_async` 

3453 

3454 """ 

3455 return await_(fn(self._connection)) 

3456 

3457 def __repr__(self) -> str: 

3458 return "<AdaptedConnection %s>" % self._connection