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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

705 statements  

1# engine/interfaces.py 

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

3# <see AUTHORS file> 

4# 

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

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

7 

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

9 

10from __future__ import annotations 

11 

12from enum import Enum 

13from typing import Any 

14from typing import Awaitable 

15from typing import Callable 

16from typing import ClassVar 

17from typing import Collection 

18from typing import Dict 

19from typing import Iterable 

20from typing import Iterator 

21from typing import List 

22from typing import Mapping 

23from typing import MutableMapping 

24from typing import Optional 

25from typing import Sequence 

26from typing import Set 

27from typing import Tuple 

28from typing import Type 

29from typing import TYPE_CHECKING 

30from typing import TypeVar 

31from typing import Union 

32 

33from .. import util 

34from ..event import EventTarget 

35from ..pool import Pool 

36from ..pool import PoolProxiedConnection as PoolProxiedConnection 

37from ..sql.compiler import Compiled as Compiled 

38from ..sql.compiler import Compiled # noqa 

39from ..sql.compiler import TypeCompiler as TypeCompiler 

40from ..sql.compiler import TypeCompiler # noqa 

41from ..util import immutabledict 

42from ..util.concurrency import await_only 

43from ..util.typing import Literal 

44from ..util.typing import NotRequired 

45from ..util.typing import Protocol 

46from ..util.typing import TypedDict 

47 

48if TYPE_CHECKING: 

49 from .base import Connection 

50 from .base import Engine 

51 from .cursor import CursorResult 

52 from .url import URL 

53 from ..connectors.asyncio import AsyncIODBAPIConnection 

54 from ..event import _ListenerFnType 

55 from ..event import dispatcher 

56 from ..exc import StatementError 

57 from ..sql import Executable 

58 from ..sql.compiler import _InsertManyValuesBatch 

59 from ..sql.compiler import DDLCompiler 

60 from ..sql.compiler import IdentifierPreparer 

61 from ..sql.compiler import InsertmanyvaluesSentinelOpts 

62 from ..sql.compiler import Linting 

63 from ..sql.compiler import SQLCompiler 

64 from ..sql.elements import BindParameter 

65 from ..sql.elements import ClauseElement 

66 from ..sql.schema import Column 

67 from ..sql.schema import DefaultGenerator 

68 from ..sql.schema import SchemaItem 

69 from ..sql.schema import Sequence as Sequence_SchemaItem 

70 from ..sql.sqltypes import Integer 

71 from ..sql.type_api import _TypeMemoDict 

72 from ..sql.type_api import TypeEngine 

73 from ..util.langhelpers import generic_fn_descriptor 

74 

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

76 

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

78 

79 

80class CacheStats(Enum): 

81 CACHE_HIT = 0 

82 CACHE_MISS = 1 

83 CACHING_DISABLED = 2 

84 NO_CACHE_KEY = 3 

85 NO_DIALECT_SUPPORT = 4 

86 

87 

88class ExecuteStyle(Enum): 

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

90 a statement.""" 

91 

92 EXECUTE = 0 

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

94 

95 EXECUTEMANY = 1 

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

97 

98 INSERTMANYVALUES = 2 

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

100 VALUES expression will be expanded to accommodate for multiple 

101 parameter sets 

102 

103 .. seealso:: 

104 

105 :ref:`engine_insertmanyvalues` 

106 

107 """ 

108 

109 

110class DBAPIModule(Protocol): 

111 class Error(Exception): 

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

113 

114 class OperationalError(Error): 

115 pass 

116 

117 class InterfaceError(Error): 

118 pass 

119 

120 class IntegrityError(Error): 

121 pass 

122 

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

124 

125 

126class DBAPIConnection(Protocol): 

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

128 

129 .. versionadded:: 2.0 

130 

131 .. seealso:: 

132 

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

134 - in :pep:`249` 

135 

136 """ # noqa: E501 

137 

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

139 

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

141 

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

143 

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

145 

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

147 

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

149 

150 

151class DBAPIType(Protocol): 

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

153 

154 .. versionadded:: 2.0 

155 

156 .. seealso:: 

157 

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

159 - in :pep:`249` 

160 

161 """ # noqa: E501 

162 

163 

164class DBAPICursor(Protocol): 

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

166 

167 .. versionadded:: 2.0 

168 

169 .. seealso:: 

170 

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

172 - in :pep:`249` 

173 

174 """ # noqa: E501 

175 

176 @property 

177 def description( 

178 self, 

179 ) -> _DBAPICursorDescription: 

180 """The description attribute of the Cursor. 

181 

182 .. seealso:: 

183 

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

185 - in :pep:`249` 

186 

187 

188 """ # noqa: E501 

189 ... 

190 

191 @property 

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

193 

194 arraysize: int 

195 

196 lastrowid: int 

197 

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

199 

200 def execute( 

201 self, 

202 operation: Any, 

203 parameters: Optional[_DBAPISingleExecuteParams] = None, 

204 ) -> Any: ... 

205 

206 def executemany( 

207 self, 

208 operation: Any, 

209 parameters: _DBAPIMultiExecuteParams, 

210 ) -> Any: ... 

211 

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

213 

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

215 

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

217 

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

219 

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

221 

222 def callproc( 

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

224 ) -> Any: ... 

225 

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

227 

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

229 

230 

231_CoreSingleExecuteParams = Mapping[str, Any] 

232_MutableCoreSingleExecuteParams = MutableMapping[str, Any] 

233_CoreMultiExecuteParams = Sequence[_CoreSingleExecuteParams] 

234_CoreAnyExecuteParams = Union[ 

235 _CoreMultiExecuteParams, _CoreSingleExecuteParams 

236] 

237 

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

239 

240_DBAPIMultiExecuteParams = Union[ 

241 Sequence[Sequence[Any]], _CoreMultiExecuteParams 

242] 

243_DBAPIAnyExecuteParams = Union[ 

244 _DBAPIMultiExecuteParams, _DBAPISingleExecuteParams 

245] 

246_DBAPICursorDescription = Sequence[ 

247 Tuple[ 

248 str, 

249 "DBAPIType", 

250 Optional[int], 

251 Optional[int], 

252 Optional[int], 

253 Optional[int], 

254 Optional[bool], 

255 ] 

256] 

257 

258_AnySingleExecuteParams = _DBAPISingleExecuteParams 

259_AnyMultiExecuteParams = _DBAPIMultiExecuteParams 

260_AnyExecuteParams = _DBAPIAnyExecuteParams 

261 

262CompiledCacheType = MutableMapping[Any, "Compiled"] 

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

264 

265_ImmutableExecuteOptions = immutabledict[str, Any] 

266 

267_ParamStyle = Literal[ 

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

269] 

270 

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

272 

273IsolationLevel = Literal[ 

274 "SERIALIZABLE", 

275 "REPEATABLE READ", 

276 "READ COMMITTED", 

277 "READ UNCOMMITTED", 

278 "AUTOCOMMIT", 

279] 

280 

281 

282class _CoreKnownExecutionOptions(TypedDict, total=False): 

283 compiled_cache: Optional[CompiledCacheType] 

284 logging_token: str 

285 isolation_level: IsolationLevel 

286 no_parameters: bool 

287 stream_results: bool 

288 max_row_buffer: int 

289 yield_per: int 

290 insertmanyvalues_page_size: int 

291 schema_translate_map: Optional[SchemaTranslateMapType] 

292 preserve_rowcount: bool 

293 

294 

295_ExecuteOptions = immutabledict[str, Any] 

296CoreExecuteOptionsParameter = Union[ 

297 _CoreKnownExecutionOptions, Mapping[str, Any] 

298] 

299 

300 

301class ReflectedIdentity(TypedDict): 

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

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

304 

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

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

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

308 

309 """ 

310 

311 always: bool 

312 """type of identity column""" 

313 

314 on_null: bool 

315 """indicates ON NULL""" 

316 

317 start: int 

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

319 

320 increment: int 

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

322 

323 minvalue: int 

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

325 

326 maxvalue: int 

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

328 

329 nominvalue: bool 

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

331 

332 nomaxvalue: bool 

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

334 

335 cycle: bool 

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

337 or minvalue has been reached.""" 

338 

339 cache: Optional[int] 

340 """number of future values in the 

341 sequence which are calculated in advance.""" 

342 

343 order: bool 

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

345 

346 

347class ReflectedComputed(TypedDict): 

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

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

350 

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

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

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

354 

355 """ 

356 

357 sqltext: str 

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

359 as a string SQL expression""" 

360 

361 persisted: NotRequired[bool] 

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

363 

364 

365class ReflectedColumn(TypedDict): 

366 """Dictionary representing the reflected elements corresponding to 

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

368 

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

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

371 

372 """ 

373 

374 name: str 

375 """column name""" 

376 

377 type: TypeEngine[Any] 

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

379 

380 nullable: bool 

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

382 

383 default: Optional[str] 

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

385 

386 autoincrement: NotRequired[bool] 

387 """database-dependent autoincrement flag. 

388 

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

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

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

392 such a flag on them. 

393 

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

395 "autoincrement". 

396 

397 """ 

398 

399 comment: NotRequired[Optional[str]] 

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

401 Only some dialects return this key 

402 """ 

403 

404 computed: NotRequired[ReflectedComputed] 

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

406 Only some dialects return this key. 

407 

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

409 """ 

410 

411 identity: NotRequired[ReflectedIdentity] 

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

413 Only some dialects return this key. 

414 

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

416 """ 

417 

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

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

420 object""" 

421 

422 

423class ReflectedConstraint(TypedDict): 

424 """Dictionary representing the reflected elements corresponding to 

425 :class:`.Constraint` 

426 

427 A base class for all constraints 

428 """ 

429 

430 name: Optional[str] 

431 """constraint name""" 

432 

433 comment: NotRequired[Optional[str]] 

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

435 

436 

437class ReflectedCheckConstraint(ReflectedConstraint): 

438 """Dictionary representing the reflected elements corresponding to 

439 :class:`.CheckConstraint`. 

440 

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

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

443 

444 """ 

445 

446 sqltext: str 

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

448 

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

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

451 

452 .. versionadded:: 1.3.8 

453 """ 

454 

455 

456class ReflectedUniqueConstraint(ReflectedConstraint): 

457 """Dictionary representing the reflected elements corresponding to 

458 :class:`.UniqueConstraint`. 

459 

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

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

462 

463 """ 

464 

465 column_names: List[str] 

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

467 

468 duplicates_index: NotRequired[Optional[str]] 

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

470 

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

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

473 constraint""" 

474 

475 

476class ReflectedPrimaryKeyConstraint(ReflectedConstraint): 

477 """Dictionary representing the reflected elements corresponding to 

478 :class:`.PrimaryKeyConstraint`. 

479 

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

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

482 

483 """ 

484 

485 constrained_columns: List[str] 

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

487 

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

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

490 

491 

492class ReflectedForeignKeyConstraint(ReflectedConstraint): 

493 """Dictionary representing the reflected elements corresponding to 

494 :class:`.ForeignKeyConstraint`. 

495 

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

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

498 

499 """ 

500 

501 constrained_columns: List[str] 

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

503 

504 referred_schema: Optional[str] 

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

506 

507 referred_table: str 

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

509 

510 referred_columns: List[str] 

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

512 

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

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

515 

516 

517class ReflectedIndex(TypedDict): 

518 """Dictionary representing the reflected elements corresponding to 

519 :class:`.Index`. 

520 

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

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

523 

524 """ 

525 

526 name: Optional[str] 

527 """index name""" 

528 

529 column_names: List[Optional[str]] 

530 """column names which the index references. 

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

532 returned in the ``expressions`` list. 

533 """ 

534 

535 expressions: NotRequired[List[str]] 

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

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

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

539 """ 

540 

541 unique: bool 

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

543 

544 duplicates_constraint: NotRequired[Optional[str]] 

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

546 

547 include_columns: NotRequired[List[str]] 

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

549 

550 .. deprecated:: 2.0 

551 

552 Legacy value, will be replaced with 

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

554 

555 """ 

556 

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

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

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

560 ``nulls_last``. 

561 

562 .. versionadded:: 1.3.5 

563 """ 

564 

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

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

567 

568 

569class ReflectedTableComment(TypedDict): 

570 """Dictionary representing the reflected comment corresponding to 

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

572 

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

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

575 

576 """ 

577 

578 text: Optional[str] 

579 """text of the comment""" 

580 

581 

582class BindTyping(Enum): 

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

584 bound parameters in a statement to the database driver. 

585 

586 .. versionadded:: 2.0 

587 

588 """ 

589 

590 NONE = 1 

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

592 

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

594 SQL Server. 

595 

596 """ 

597 

598 SETINPUTSIZES = 2 

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

600 

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

602 the SQLAlchemy dialect has the appropriate infrastructure for that dialect 

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

604 optional support for SQL Server using pyodbc. 

605 

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

607 method for certain datatypes using include/exclude lists. 

608 

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

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

611 

612 """ 

613 

614 RENDER_CASTS = 3 

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

616 

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

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

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

620 aren't. 

621 

622 When RENDER_CASTS is used, the compiler will invoke the 

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

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

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

626 

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

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

629 :attr:`.InsertmanyvaluesSentinelOpts.USE_INSERT_FROM_SELECT` and 

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

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

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

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

634 

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

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

637 

638 

639 """ 

640 

641 

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

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

644 

645 

646class Dialect(EventTarget): 

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

648 

649 Any aspect of metadata definition, SQL query generation, 

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

651 between databases is defined under the general category of the 

652 Dialect. The Dialect acts as a factory for other 

653 database-specific object implementations including 

654 ExecutionContext, Compiled, DefaultGenerator, and TypeEngine. 

655 

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

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

658 descendant class. 

659 

660 """ 

661 

662 CACHE_HIT = CacheStats.CACHE_HIT 

663 CACHE_MISS = CacheStats.CACHE_MISS 

664 CACHING_DISABLED = CacheStats.CACHING_DISABLED 

665 NO_CACHE_KEY = CacheStats.NO_CACHE_KEY 

666 NO_DIALECT_SUPPORT = CacheStats.NO_DIALECT_SUPPORT 

667 

668 dispatch: dispatcher[Dialect] 

669 

670 name: str 

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

672 (i.e. 'sqlite') 

673 """ 

674 

675 driver: str 

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

677 

678 dialect_description: str 

679 

680 dbapi: Optional[DBAPIModule] 

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

682 

683 SQLAlchemy dialects import DBAPI modules using the classmethod 

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

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

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

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

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

689 the DBAPI module to this attribute. 

690 

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

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

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

694 contents. 

695 

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

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

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

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

700 

701 """ 

702 

703 @util.non_memoized_property 

704 def loaded_dbapi(self) -> DBAPIModule: 

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

706 DBAPI was set up. 

707 

708 .. versionadded:: 2.0 

709 

710 """ 

711 raise NotImplementedError() 

712 

713 positional: bool 

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

715 

716 paramstyle: str 

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

718 paramstyles). 

719 """ 

720 

721 compiler_linting: Linting 

722 

723 statement_compiler: Type[SQLCompiler] 

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

725 

726 ddl_compiler: Type[DDLCompiler] 

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

728 

729 type_compiler_cls: ClassVar[Type[TypeCompiler]] 

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

731 

732 .. versionadded:: 2.0 

733 

734 """ 

735 

736 type_compiler_instance: TypeCompiler 

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

738 objects 

739 

740 .. versionadded:: 2.0 

741 

742 """ 

743 

744 type_compiler: Any 

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

746 TypeCompiler instance at the instance level. 

747 

748 Refer to type_compiler_instance instead. 

749 

750 """ 

751 

752 preparer: Type[IdentifierPreparer] 

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

754 quote identifiers. 

755 """ 

756 

757 identifier_preparer: IdentifierPreparer 

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

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

760 

761 """ 

762 

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

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

765 

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

767 typically populated during the initial connection to the database. 

768 """ 

769 

770 default_schema_name: Optional[str] 

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

772 supporting dialects, and is typically populated during the 

773 initial connection to the database. 

774 

775 """ 

776 

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

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

779 default_isolation_level: Optional[IsolationLevel] 

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

781 

782 skip_autocommit_rollback: bool 

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

784 parameter was set. 

785 

786 .. versionadded:: 2.0.43 

787 

788 """ 

789 

790 # create_engine() -> isolation_level currently goes here 

791 _on_connect_isolation_level: Optional[IsolationLevel] 

792 

793 execution_ctx_cls: Type[ExecutionContext] 

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

795 

796 execute_sequence_format: Union[ 

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

798 ] 

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

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

801 

802 supports_alter: bool 

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

804 generating foreign key constraints in certain circumstances 

805 """ 

806 

807 max_identifier_length: int 

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

809 max_index_name_length: Optional[int] 

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

811 ``max_identifier_length``.""" 

812 max_constraint_name_length: Optional[int] 

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

814 ``max_identifier_length``.""" 

815 

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

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

818 

819 server_side_cursors: bool 

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

821 side cursors by default""" 

822 

823 supports_sane_rowcount: bool 

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

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

826 """ 

827 

828 supports_sane_multi_rowcount: bool 

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

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

831 executemany. 

832 """ 

833 

834 supports_empty_insert: bool 

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

836 columns in it. 

837 

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

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

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

841 

842 """ 

843 

844 supports_default_values: bool 

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

846 

847 supports_default_metavalue: bool 

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

849 

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

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

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

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

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

855 

856 """ 

857 

858 default_metavalue_token: str = "DEFAULT" 

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

860 parenthesis. 

861 

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

863 

864 """ 

865 

866 supports_multivalues_insert: bool 

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

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

869 

870 """ 

871 

872 insert_executemany_returning: bool 

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

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

875 

876 """ 

877 

878 insert_executemany_returning_sort_by_parameter_order: bool 

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

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

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

882 parameter being set. 

883 

884 """ 

885 

886 update_executemany_returning: bool 

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

888 

889 delete_executemany_returning: bool 

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

891 

892 use_insertmanyvalues: bool 

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

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

895 

896 In practice, setting this to True means: 

897 

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

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

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

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

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

903 INSERT statement to have multiple VALUES clauses, also executing 

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

905 of rows are given. 

906 

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

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

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

910 with RETURNING" support and also does not support 

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

912 that don't support RETURNING will not report 

913 ``insert_executemany_returning`` as True. 

914 

915 .. versionadded:: 2.0 

916 

917 .. seealso:: 

918 

919 :ref:`engine_insertmanyvalues` 

920 

921 """ 

922 

923 use_insertmanyvalues_wo_returning: bool 

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

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

926 

927 .. versionadded:: 2.0 

928 

929 .. seealso:: 

930 

931 :ref:`engine_insertmanyvalues` 

932 

933 """ 

934 

935 insertmanyvalues_implicit_sentinel: InsertmanyvaluesSentinelOpts 

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

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

938 for INSERTed rows. 

939 

940 .. versionadded:: 2.0.10 

941 

942 .. seealso:: 

943 

944 :ref:`engine_insertmanyvalues_returning_order` 

945 

946 """ 

947 

948 insertmanyvalues_page_size: int 

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

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

951 

952 The default dialect defaults this to 1000. 

953 

954 .. versionadded:: 2.0 

955 

956 .. seealso:: 

957 

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

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

960 

961 """ # noqa: E501 

962 

963 insertmanyvalues_max_parameters: int 

964 """Alternate to insertmanyvalues_page_size, will additionally limit 

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

966 

967 

968 """ 

969 

970 preexecute_autoincrement_sequences: bool 

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

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

973 

974 This is currently oriented towards PostgreSQL when the 

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

976 object. 

977 

978 """ 

979 

980 insert_returning: bool 

981 """if the dialect supports RETURNING with INSERT 

982 

983 .. versionadded:: 2.0 

984 

985 """ 

986 

987 update_returning: bool 

988 """if the dialect supports RETURNING with UPDATE 

989 

990 .. versionadded:: 2.0 

991 

992 """ 

993 

994 update_returning_multifrom: bool 

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

996 

997 .. versionadded:: 2.0 

998 

999 """ 

1000 

1001 delete_returning: bool 

1002 """if the dialect supports RETURNING with DELETE 

1003 

1004 .. versionadded:: 2.0 

1005 

1006 """ 

1007 

1008 delete_returning_multifrom: bool 

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

1010 

1011 .. versionadded:: 2.0 

1012 

1013 """ 

1014 

1015 favor_returning_over_lastrowid: bool 

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

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

1018 

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

1020 

1021 """ 

1022 

1023 supports_identity_columns: bool 

1024 """target database supports IDENTITY""" 

1025 

1026 cte_follows_insert: bool 

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

1028 the CTE to be below the INSERT""" 

1029 

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

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

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

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

1034 dialect instance itself. 

1035 """ 

1036 

1037 supports_sequences: bool 

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

1039 

1040 sequences_optional: bool 

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

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

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

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

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

1046 other backends. 

1047 """ 

1048 

1049 default_sequence_base: int 

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

1051 a CREATE SEQUENCE DDL statement. 

1052 

1053 """ 

1054 

1055 supports_native_enum: bool 

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

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

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

1059 """ 

1060 

1061 supports_native_boolean: bool 

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

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

1064 constraint when that type is used. 

1065 """ 

1066 

1067 supports_native_decimal: bool 

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

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

1070 

1071 supports_native_uuid: bool 

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

1073 driver for SQL UUID datatypes. 

1074 

1075 .. versionadded:: 2.0 

1076 

1077 """ 

1078 

1079 returns_native_bytes: bool 

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

1081 driver for SQL "binary" datatypes. 

1082 

1083 .. versionadded:: 2.0.11 

1084 

1085 """ 

1086 

1087 construct_arguments: Optional[ 

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

1089 ] = None 

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

1091 constructs, typically schema items. 

1092 

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

1094 

1095 construct_arguments = [ 

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

1097 ] 

1098 

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

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

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

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

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

1104 

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

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

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

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

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

1110 feature continue to function in the old way. 

1111 

1112 .. seealso:: 

1113 

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

1115 :attr:`.DefaultDialect.construct_arguments` 

1116 

1117 

1118 """ 

1119 

1120 reflection_options: Sequence[str] = () 

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

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

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

1124 

1125 Current example is "oracle_resolve_synonyms" in the Oracle Database 

1126 dialects. 

1127 

1128 """ 

1129 

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

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

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

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

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

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

1136 majority of cases this dictionary is empty. 

1137 """ 

1138 

1139 supports_comments: bool 

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

1141 

1142 inline_comments: bool 

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

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

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

1146 

1147 supports_constraint_comments: bool 

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

1149 

1150 .. versionadded:: 2.0 

1151 """ 

1152 

1153 _has_events = False 

1154 

1155 supports_statement_cache: bool = True 

1156 """indicates if this dialect supports caching. 

1157 

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

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

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

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

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

1163 compliant with SQL statement caching. 

1164 

1165 .. versionadded:: 1.4.5 

1166 

1167 .. seealso:: 

1168 

1169 :ref:`engine_thirdparty_caching` 

1170 

1171 """ 

1172 

1173 _supports_statement_cache: bool 

1174 """internal evaluation for supports_statement_cache""" 

1175 

1176 bind_typing = BindTyping.NONE 

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

1178 driver for bound parameters. 

1179 

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

1181 

1182 .. versionadded:: 2.0 

1183 

1184 """ 

1185 

1186 is_async: bool 

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

1188 

1189 has_terminate: bool 

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

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

1192 

1193 engine_config_types: Mapping[str, Any] 

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

1195 type conversion functions. 

1196 

1197 """ 

1198 

1199 label_length: Optional[int] 

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

1201 

1202 include_set_input_sizes: Optional[Set[Any]] 

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

1204 automatic cursor.setinputsizes() calls. 

1205 

1206 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 

1207 

1208 """ 

1209 

1210 exclude_set_input_sizes: Optional[Set[Any]] 

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

1212 automatic cursor.setinputsizes() calls. 

1213 

1214 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 

1215 

1216 """ 

1217 

1218 supports_simple_order_by_label: bool 

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

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

1221 

1222 div_is_floordiv: bool 

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

1224 

1225 tuple_in_values: bool 

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

1227 

1228 requires_name_normalize: bool 

1229 """Indicates symbol names are returned by the database in 

1230 UPPERCASED if they are case insensitive within the database. 

1231 If this is True, the methods normalize_name() 

1232 and denormalize_name() must be provided. 

1233 """ 

1234 

1235 _bind_typing_render_casts: bool 

1236 

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

1238 

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

1240 raise NotImplementedError() 

1241 

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

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

1244 

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

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

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

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

1249 ``connect()`` function. 

1250 

1251 The method typically makes use of the 

1252 :meth:`.URL.translate_connect_args` 

1253 method in order to generate a dictionary of options. 

1254 

1255 The default implementation is:: 

1256 

1257 def create_connect_args(self, url): 

1258 opts = url.translate_connect_args() 

1259 opts.update(url.query) 

1260 return ([], opts) 

1261 

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

1263 

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

1265 :meth:`.Dialect.connect` method. 

1266 

1267 .. seealso:: 

1268 

1269 :meth:`.URL.translate_connect_args` 

1270 

1271 """ 

1272 

1273 raise NotImplementedError() 

1274 

1275 @classmethod 

1276 def import_dbapi(cls) -> DBAPIModule: 

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

1278 

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

1280 instance variable to a constructed dialect under the name 

1281 ``.dbapi``. 

1282 

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

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

1285 which would be replaced at dialect instantiation time by the 

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

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

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

1289 

1290 """ 

1291 raise NotImplementedError() 

1292 

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

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

1295 

1296 Dialect classes will usually use the 

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

1298 accomplish this. 

1299 

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

1301 contain no dialect-instance state. 

1302 

1303 """ 

1304 

1305 raise NotImplementedError() 

1306 

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

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

1309 connection. 

1310 

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

1312 other properties. 

1313 

1314 The connection passed here is a SQLAlchemy Connection object, 

1315 with full capabilities. 

1316 

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

1318 super(). 

1319 

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

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

1322 

1323 """ 

1324 

1325 if TYPE_CHECKING: 

1326 

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

1328 

1329 def get_columns( 

1330 self, 

1331 connection: Connection, 

1332 table_name: str, 

1333 schema: Optional[str] = None, 

1334 **kw: Any, 

1335 ) -> List[ReflectedColumn]: 

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

1337 

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

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

1340 information as a list of dictionaries 

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

1342 

1343 This is an internal dialect method. Applications should use 

1344 :meth:`.Inspector.get_columns`. 

1345 

1346 """ 

1347 

1348 raise NotImplementedError() 

1349 

1350 def get_multi_columns( 

1351 self, 

1352 connection: Connection, 

1353 *, 

1354 schema: Optional[str] = None, 

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

1356 **kw: Any, 

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

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

1359 given ``schema``. 

1360 

1361 This is an internal dialect method. Applications should use 

1362 :meth:`.Inspector.get_multi_columns`. 

1363 

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

1365 implementation that will call the single table method for 

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

1367 :meth:`Dialect.get_view_names` or 

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

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

1370 implementation should implement this method. 

1371 

1372 .. versionadded:: 2.0 

1373 

1374 """ 

1375 

1376 raise NotImplementedError() 

1377 

1378 def get_pk_constraint( 

1379 self, 

1380 connection: Connection, 

1381 table_name: str, 

1382 schema: Optional[str] = None, 

1383 **kw: Any, 

1384 ) -> ReflectedPrimaryKeyConstraint: 

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

1386 table_name`. 

1387 

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

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

1390 key information as a dictionary corresponding to the 

1391 :class:`.ReflectedPrimaryKeyConstraint` dictionary. 

1392 

1393 This is an internal dialect method. Applications should use 

1394 :meth:`.Inspector.get_pk_constraint`. 

1395 

1396 """ 

1397 raise NotImplementedError() 

1398 

1399 def get_multi_pk_constraint( 

1400 self, 

1401 connection: Connection, 

1402 *, 

1403 schema: Optional[str] = None, 

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

1405 **kw: Any, 

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

1407 """Return information about primary key constraints in 

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

1409 

1410 This is an internal dialect method. Applications should use 

1411 :meth:`.Inspector.get_multi_pk_constraint`. 

1412 

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

1414 implementation that will call the single table method for 

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

1416 :meth:`Dialect.get_view_names` or 

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

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

1419 implementation should implement this method. 

1420 

1421 .. versionadded:: 2.0 

1422 

1423 """ 

1424 raise NotImplementedError() 

1425 

1426 def get_foreign_keys( 

1427 self, 

1428 connection: Connection, 

1429 table_name: str, 

1430 schema: Optional[str] = None, 

1431 **kw: Any, 

1432 ) -> List[ReflectedForeignKeyConstraint]: 

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

1434 

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

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

1437 key information as a list of dicts corresponding to the 

1438 :class:`.ReflectedForeignKeyConstraint` dictionary. 

1439 

1440 This is an internal dialect method. Applications should use 

1441 :meth:`_engine.Inspector.get_foreign_keys`. 

1442 """ 

1443 

1444 raise NotImplementedError() 

1445 

1446 def get_multi_foreign_keys( 

1447 self, 

1448 connection: Connection, 

1449 *, 

1450 schema: Optional[str] = None, 

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

1452 **kw: Any, 

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

1454 """Return information about foreign_keys in all tables 

1455 in the given ``schema``. 

1456 

1457 This is an internal dialect method. Applications should use 

1458 :meth:`_engine.Inspector.get_multi_foreign_keys`. 

1459 

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

1461 implementation that will call the single table method for 

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

1463 :meth:`Dialect.get_view_names` or 

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

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

1466 implementation should implement this method. 

1467 

1468 .. versionadded:: 2.0 

1469 

1470 """ 

1471 

1472 raise NotImplementedError() 

1473 

1474 def get_table_names( 

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

1476 ) -> List[str]: 

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

1478 

1479 This is an internal dialect method. Applications should use 

1480 :meth:`_engine.Inspector.get_table_names`. 

1481 

1482 """ 

1483 

1484 raise NotImplementedError() 

1485 

1486 def get_temp_table_names( 

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

1488 ) -> List[str]: 

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

1490 if supported by the underlying backend. 

1491 

1492 This is an internal dialect method. Applications should use 

1493 :meth:`_engine.Inspector.get_temp_table_names`. 

1494 

1495 """ 

1496 

1497 raise NotImplementedError() 

1498 

1499 def get_view_names( 

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

1501 ) -> List[str]: 

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

1503 database. 

1504 

1505 This is an internal dialect method. Applications should use 

1506 :meth:`_engine.Inspector.get_view_names`. 

1507 

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

1509 

1510 """ 

1511 

1512 raise NotImplementedError() 

1513 

1514 def get_materialized_view_names( 

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

1516 ) -> List[str]: 

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

1518 database. 

1519 

1520 This is an internal dialect method. Applications should use 

1521 :meth:`_engine.Inspector.get_materialized_view_names`. 

1522 

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

1524 

1525 .. versionadded:: 2.0 

1526 

1527 """ 

1528 

1529 raise NotImplementedError() 

1530 

1531 def get_sequence_names( 

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

1533 ) -> List[str]: 

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

1535 

1536 This is an internal dialect method. Applications should use 

1537 :meth:`_engine.Inspector.get_sequence_names`. 

1538 

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

1540 

1541 .. versionadded:: 1.4 

1542 """ 

1543 

1544 raise NotImplementedError() 

1545 

1546 def get_temp_view_names( 

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

1548 ) -> List[str]: 

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

1550 if supported by the underlying backend. 

1551 

1552 This is an internal dialect method. Applications should use 

1553 :meth:`_engine.Inspector.get_temp_view_names`. 

1554 

1555 """ 

1556 

1557 raise NotImplementedError() 

1558 

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

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

1561 

1562 This is an internal dialect method. Applications should use 

1563 :meth:`_engine.Inspector.get_schema_names`. 

1564 """ 

1565 raise NotImplementedError() 

1566 

1567 def get_view_definition( 

1568 self, 

1569 connection: Connection, 

1570 view_name: str, 

1571 schema: Optional[str] = None, 

1572 **kw: Any, 

1573 ) -> str: 

1574 """Return plain or materialized view definition. 

1575 

1576 This is an internal dialect method. Applications should use 

1577 :meth:`_engine.Inspector.get_view_definition`. 

1578 

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

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

1581 definition. 

1582 """ 

1583 

1584 raise NotImplementedError() 

1585 

1586 def get_indexes( 

1587 self, 

1588 connection: Connection, 

1589 table_name: str, 

1590 schema: Optional[str] = None, 

1591 **kw: Any, 

1592 ) -> List[ReflectedIndex]: 

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

1594 

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

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

1597 information as a list of dictionaries corresponding to the 

1598 :class:`.ReflectedIndex` dictionary. 

1599 

1600 This is an internal dialect method. Applications should use 

1601 :meth:`.Inspector.get_indexes`. 

1602 """ 

1603 

1604 raise NotImplementedError() 

1605 

1606 def get_multi_indexes( 

1607 self, 

1608 connection: Connection, 

1609 *, 

1610 schema: Optional[str] = None, 

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

1612 **kw: Any, 

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

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

1615 in the given ``schema``. 

1616 

1617 This is an internal dialect method. Applications should use 

1618 :meth:`.Inspector.get_multi_indexes`. 

1619 

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

1621 implementation that will call the single table method for 

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

1623 :meth:`Dialect.get_view_names` or 

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

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

1626 implementation should implement this method. 

1627 

1628 .. versionadded:: 2.0 

1629 

1630 """ 

1631 

1632 raise NotImplementedError() 

1633 

1634 def get_unique_constraints( 

1635 self, 

1636 connection: Connection, 

1637 table_name: str, 

1638 schema: Optional[str] = None, 

1639 **kw: Any, 

1640 ) -> List[ReflectedUniqueConstraint]: 

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

1642 

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

1644 unique constraint information as a list of dicts corresponding 

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

1646 

1647 This is an internal dialect method. Applications should use 

1648 :meth:`.Inspector.get_unique_constraints`. 

1649 """ 

1650 

1651 raise NotImplementedError() 

1652 

1653 def get_multi_unique_constraints( 

1654 self, 

1655 connection: Connection, 

1656 *, 

1657 schema: Optional[str] = None, 

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

1659 **kw: Any, 

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

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

1662 in the given ``schema``. 

1663 

1664 This is an internal dialect method. Applications should use 

1665 :meth:`.Inspector.get_multi_unique_constraints`. 

1666 

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

1668 implementation that will call the single table method for 

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

1670 :meth:`Dialect.get_view_names` or 

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

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

1673 implementation should implement this method. 

1674 

1675 .. versionadded:: 2.0 

1676 

1677 """ 

1678 

1679 raise NotImplementedError() 

1680 

1681 def get_check_constraints( 

1682 self, 

1683 connection: Connection, 

1684 table_name: str, 

1685 schema: Optional[str] = None, 

1686 **kw: Any, 

1687 ) -> List[ReflectedCheckConstraint]: 

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

1689 

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

1691 check constraint information as a list of dicts corresponding 

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

1693 

1694 This is an internal dialect method. Applications should use 

1695 :meth:`.Inspector.get_check_constraints`. 

1696 

1697 """ 

1698 

1699 raise NotImplementedError() 

1700 

1701 def get_multi_check_constraints( 

1702 self, 

1703 connection: Connection, 

1704 *, 

1705 schema: Optional[str] = None, 

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

1707 **kw: Any, 

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

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

1710 in the given ``schema``. 

1711 

1712 This is an internal dialect method. Applications should use 

1713 :meth:`.Inspector.get_multi_check_constraints`. 

1714 

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

1716 implementation that will call the single table method for 

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

1718 :meth:`Dialect.get_view_names` or 

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

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

1721 implementation should implement this method. 

1722 

1723 .. versionadded:: 2.0 

1724 

1725 """ 

1726 

1727 raise NotImplementedError() 

1728 

1729 def get_table_options( 

1730 self, 

1731 connection: Connection, 

1732 table_name: str, 

1733 schema: Optional[str] = None, 

1734 **kw: Any, 

1735 ) -> Dict[str, Any]: 

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

1737 was created. 

1738 

1739 This is an internal dialect method. Applications should use 

1740 :meth:`_engine.Inspector.get_table_options`. 

1741 """ 

1742 raise NotImplementedError() 

1743 

1744 def get_multi_table_options( 

1745 self, 

1746 connection: Connection, 

1747 *, 

1748 schema: Optional[str] = None, 

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

1750 **kw: Any, 

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

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

1753 given schema were created. 

1754 

1755 This is an internal dialect method. Applications should use 

1756 :meth:`_engine.Inspector.get_multi_table_options`. 

1757 

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

1759 implementation that will call the single table method for 

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

1761 :meth:`Dialect.get_view_names` or 

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

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

1764 implementation should implement this method. 

1765 

1766 .. versionadded:: 2.0 

1767 

1768 """ 

1769 raise NotImplementedError() 

1770 

1771 def get_table_comment( 

1772 self, 

1773 connection: Connection, 

1774 table_name: str, 

1775 schema: Optional[str] = None, 

1776 **kw: Any, 

1777 ) -> ReflectedTableComment: 

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

1779 

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

1781 table comment information as a dictionary corresponding to the 

1782 :class:`.ReflectedTableComment` dictionary. 

1783 

1784 This is an internal dialect method. Applications should use 

1785 :meth:`.Inspector.get_table_comment`. 

1786 

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

1788 comments. 

1789 

1790 .. versionadded:: 1.2 

1791 

1792 """ 

1793 

1794 raise NotImplementedError() 

1795 

1796 def get_multi_table_comment( 

1797 self, 

1798 connection: Connection, 

1799 *, 

1800 schema: Optional[str] = None, 

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

1802 **kw: Any, 

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

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

1805 in the given ``schema``. 

1806 

1807 This is an internal dialect method. Applications should use 

1808 :meth:`_engine.Inspector.get_multi_table_comment`. 

1809 

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

1811 implementation that will call the single table method for 

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

1813 :meth:`Dialect.get_view_names` or 

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

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

1816 implementation should implement this method. 

1817 

1818 .. versionadded:: 2.0 

1819 

1820 """ 

1821 

1822 raise NotImplementedError() 

1823 

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

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

1826 case insensitive. 

1827 

1828 This method is only used if the dialect defines 

1829 requires_name_normalize=True. 

1830 

1831 """ 

1832 raise NotImplementedError() 

1833 

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

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

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

1837 

1838 This method is only used if the dialect defines 

1839 requires_name_normalize=True. 

1840 

1841 """ 

1842 raise NotImplementedError() 

1843 

1844 def has_table( 

1845 self, 

1846 connection: Connection, 

1847 table_name: str, 

1848 schema: Optional[str] = None, 

1849 **kw: Any, 

1850 ) -> bool: 

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

1852 or view in the database. 

1853 

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

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

1856 database, False otherwise. 

1857 

1858 This method serves as the underlying implementation of the 

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

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

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

1862 

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

1864 published so that third-party dialects may provide an 

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

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

1867 

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

1869 formally supports checking for additional table-like objects: 

1870 

1871 * any type of views (plain or materialized) 

1872 * temporary tables of any kind 

1873 

1874 Previously, these two checks were not formally specified and 

1875 different dialects would vary in their behavior. The dialect 

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

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

1878 or temporary tables should seek to support locating these objects 

1879 for full compliance. 

1880 

1881 """ 

1882 

1883 raise NotImplementedError() 

1884 

1885 def has_index( 

1886 self, 

1887 connection: Connection, 

1888 table_name: str, 

1889 index_name: str, 

1890 schema: Optional[str] = None, 

1891 **kw: Any, 

1892 ) -> bool: 

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

1894 

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

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

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

1898 

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

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

1901 however dialects can implement a more performant version. 

1902 

1903 This is an internal dialect method. Applications should use 

1904 :meth:`_engine.Inspector.has_index`. 

1905 

1906 .. versionadded:: 1.4 

1907 

1908 """ 

1909 

1910 raise NotImplementedError() 

1911 

1912 def has_sequence( 

1913 self, 

1914 connection: Connection, 

1915 sequence_name: str, 

1916 schema: Optional[str] = None, 

1917 **kw: Any, 

1918 ) -> bool: 

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

1920 

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

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

1923 the database, ``False`` otherwise. 

1924 

1925 This is an internal dialect method. Applications should use 

1926 :meth:`_engine.Inspector.has_sequence`. 

1927 """ 

1928 

1929 raise NotImplementedError() 

1930 

1931 def has_schema( 

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

1933 ) -> bool: 

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

1935 

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

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

1938 given exists, ``False`` otherwise. 

1939 

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

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

1942 :meth:`.Dialect.get_schema_names`, 

1943 however dialects can implement a more performant version. 

1944 

1945 This is an internal dialect method. Applications should use 

1946 :meth:`_engine.Inspector.has_schema`. 

1947 

1948 .. versionadded:: 2.0 

1949 

1950 """ 

1951 

1952 raise NotImplementedError() 

1953 

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

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

1956 

1957 This is used by the default implementation to populate the 

1958 "server_version_info" attribute and is called exactly 

1959 once upon first connect. 

1960 

1961 """ 

1962 

1963 raise NotImplementedError() 

1964 

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

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

1967 the given connection. 

1968 

1969 This is used by the default implementation to populate the 

1970 "default_schema_name" attribute and is called exactly 

1971 once upon first connect. 

1972 

1973 """ 

1974 

1975 raise NotImplementedError() 

1976 

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

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

1979 DB-API connection. 

1980 

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

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

1983 DBAPIs that might need additional help in this area. 

1984 

1985 :param dbapi_connection: a DBAPI connection, typically 

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

1987 

1988 """ 

1989 

1990 raise NotImplementedError() 

1991 

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

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

1994 a DB-API connection. 

1995 

1996 :param dbapi_connection: a DBAPI connection, typically 

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

1998 

1999 """ 

2000 

2001 raise NotImplementedError() 

2002 

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

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

2005 DB-API connection. 

2006 

2007 :param dbapi_connection: a DBAPI connection, typically 

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

2009 

2010 """ 

2011 

2012 raise NotImplementedError() 

2013 

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

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

2016 much as possible to not block, given a DBAPI 

2017 connection. 

2018 

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

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

2021 

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

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

2024 

2025 .. versionadded:: 1.4.41 

2026 

2027 """ 

2028 

2029 raise NotImplementedError() 

2030 

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

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

2033 connection. 

2034 

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

2036 when a connection has been 

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

2038 capacity of the pool. 

2039 

2040 """ 

2041 

2042 raise NotImplementedError() 

2043 

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

2045 raise NotImplementedError() 

2046 

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

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

2049 usable.""" 

2050 raise NotImplementedError() 

2051 

2052 def do_set_input_sizes( 

2053 self, 

2054 cursor: DBAPICursor, 

2055 list_of_tuples: _GenericSetInputSizesType, 

2056 context: ExecutionContext, 

2057 ) -> Any: 

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

2059 

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

2061 set to the 

2062 :attr:`.BindTyping.SETINPUTSIZES` value. 

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

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

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

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

2067 

2068 .. versionadded:: 1.4 

2069 

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

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

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

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

2074 appropriately. 

2075 

2076 

2077 """ 

2078 raise NotImplementedError() 

2079 

2080 def create_xid(self) -> Any: 

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

2082 

2083 This id will be passed to do_begin_twophase(), 

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

2085 unspecified. 

2086 """ 

2087 

2088 raise NotImplementedError() 

2089 

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

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

2092 

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

2094 :param name: savepoint name. 

2095 

2096 """ 

2097 

2098 raise NotImplementedError() 

2099 

2100 def do_rollback_to_savepoint( 

2101 self, connection: Connection, name: str 

2102 ) -> None: 

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

2104 

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

2106 :param name: savepoint name. 

2107 

2108 """ 

2109 

2110 raise NotImplementedError() 

2111 

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

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

2114 

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

2116 :param name: savepoint name. 

2117 """ 

2118 

2119 raise NotImplementedError() 

2120 

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

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

2123 

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

2125 :param xid: xid 

2126 

2127 """ 

2128 

2129 raise NotImplementedError() 

2130 

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

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

2133 

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

2135 :param xid: xid 

2136 

2137 """ 

2138 

2139 raise NotImplementedError() 

2140 

2141 def do_rollback_twophase( 

2142 self, 

2143 connection: Connection, 

2144 xid: Any, 

2145 is_prepared: bool = True, 

2146 recover: bool = False, 

2147 ) -> None: 

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

2149 

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

2151 :param xid: xid 

2152 :param is_prepared: whether or not 

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

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

2155 

2156 """ 

2157 

2158 raise NotImplementedError() 

2159 

2160 def do_commit_twophase( 

2161 self, 

2162 connection: Connection, 

2163 xid: Any, 

2164 is_prepared: bool = True, 

2165 recover: bool = False, 

2166 ) -> None: 

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

2168 

2169 

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

2171 :param xid: xid 

2172 :param is_prepared: whether or not 

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

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

2175 

2176 """ 

2177 

2178 raise NotImplementedError() 

2179 

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

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

2182 identifiers on the given connection. 

2183 

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

2185 

2186 """ 

2187 

2188 raise NotImplementedError() 

2189 

2190 def _deliver_insertmanyvalues_batches( 

2191 self, 

2192 connection: Connection, 

2193 cursor: DBAPICursor, 

2194 statement: str, 

2195 parameters: _DBAPIMultiExecuteParams, 

2196 generic_setinputsizes: Optional[_GenericSetInputSizesType], 

2197 context: ExecutionContext, 

2198 ) -> Iterator[_InsertManyValuesBatch]: 

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

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

2201 feature. 

2202 

2203 """ 

2204 raise NotImplementedError() 

2205 

2206 def do_executemany( 

2207 self, 

2208 cursor: DBAPICursor, 

2209 statement: str, 

2210 parameters: _DBAPIMultiExecuteParams, 

2211 context: Optional[ExecutionContext] = None, 

2212 ) -> None: 

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

2214 parameters)``.""" 

2215 

2216 raise NotImplementedError() 

2217 

2218 def do_execute( 

2219 self, 

2220 cursor: DBAPICursor, 

2221 statement: str, 

2222 parameters: Optional[_DBAPISingleExecuteParams], 

2223 context: Optional[ExecutionContext] = None, 

2224 ) -> None: 

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

2226 parameters)``.""" 

2227 

2228 raise NotImplementedError() 

2229 

2230 def do_execute_no_params( 

2231 self, 

2232 cursor: DBAPICursor, 

2233 statement: str, 

2234 context: Optional[ExecutionContext] = None, 

2235 ) -> None: 

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

2237 

2238 The parameter collection should not be sent. 

2239 

2240 """ 

2241 

2242 raise NotImplementedError() 

2243 

2244 def is_disconnect( 

2245 self, 

2246 e: DBAPIModule.Error, 

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

2248 cursor: Optional[DBAPICursor], 

2249 ) -> bool: 

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

2251 connection""" 

2252 

2253 raise NotImplementedError() 

2254 

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

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

2257 

2258 The default implementation of this method is:: 

2259 

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

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

2262 

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

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

2265 

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

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

2268 DBAPI. 

2269 

2270 

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

2272 :meth:`.Dialect.create_connect_args` method 

2273 

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

2275 :meth:`.Dialect.create_connect_args` method. 

2276 

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

2278 level ``.connect()`` function. 

2279 

2280 .. seealso:: 

2281 

2282 :meth:`.Dialect.create_connect_args` 

2283 

2284 :meth:`.Dialect.on_connect` 

2285 

2286 """ 

2287 raise NotImplementedError() 

2288 

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

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

2291 

2292 This method is a new hook that supersedes the 

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

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

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

2296 compatibility with existing dialects. There is no deprecation 

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

2298 

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

2300 DBAPI connection itself. The inner callable has no 

2301 return value. 

2302 

2303 E.g.:: 

2304 

2305 class MyDialect(default.DefaultDialect): 

2306 # ... 

2307 

2308 def on_connect_url(self, url): 

2309 def do_on_connect(connection): 

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

2311 

2312 return do_on_connect 

2313 

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

2315 isolation modes, Unicode modes, etc. 

2316 

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

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

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

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

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

2322 replaced by plugins. 

2323 

2324 .. note:: 

2325 

2326 The default implementation of 

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

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

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

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

2331 it directly from here. 

2332 

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

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

2335 

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

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

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

2339 

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

2341 argument, or None. 

2342 

2343 .. seealso:: 

2344 

2345 :meth:`_engine.Dialect.on_connect` 

2346 

2347 """ 

2348 return self.on_connect() 

2349 

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

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

2352 

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

2354 DBAPI connection itself. The inner callable has no 

2355 return value. 

2356 

2357 E.g.:: 

2358 

2359 class MyDialect(default.DefaultDialect): 

2360 # ... 

2361 

2362 def on_connect(self): 

2363 def do_on_connect(connection): 

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

2365 

2366 return do_on_connect 

2367 

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

2369 isolation modes, Unicode modes, etc. 

2370 

2371 The "do_on_connect" callable is invoked by using the 

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

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

2374 callable. 

2375 

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

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

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

2379 

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

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

2382 the connect args. Dialects can implement on_connect_url instead 

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

2384 connection in order to get additional context. 

2385 

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

2387 

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

2389 argument, or None. 

2390 

2391 .. seealso:: 

2392 

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

2394 itself to be controlled. 

2395 

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

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

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

2399 

2400 """ 

2401 return None 

2402 

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

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

2405 

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

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

2408 :class:`_engine.Engine` 

2409 isolation level facilities; these APIs should be preferred for 

2410 most typical use cases. 

2411 

2412 .. seealso:: 

2413 

2414 :meth:`_engine.Connection.get_isolation_level` 

2415 - view current level 

2416 

2417 :attr:`_engine.Connection.default_isolation_level` 

2418 - view default level 

2419 

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

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

2422 

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

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

2425 

2426 """ 

2427 

2428 raise NotImplementedError() 

2429 

2430 def set_isolation_level( 

2431 self, dbapi_connection: DBAPIConnection, level: IsolationLevel 

2432 ) -> None: 

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

2434 

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

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

2437 :class:`_engine.Engine` 

2438 isolation level facilities; these APIs should be preferred for 

2439 most typical use cases. 

2440 

2441 If the dialect also implements the 

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

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

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

2445 

2446 .. seealso:: 

2447 

2448 :meth:`_engine.Connection.get_isolation_level` 

2449 - view current level 

2450 

2451 :attr:`_engine.Connection.default_isolation_level` 

2452 - view default level 

2453 

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

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

2456 

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

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

2459 

2460 """ 

2461 

2462 raise NotImplementedError() 

2463 

2464 def get_isolation_level( 

2465 self, dbapi_connection: DBAPIConnection 

2466 ) -> IsolationLevel: 

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

2468 

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

2470 the corresponding 

2471 DBAPI connection may be procured using the 

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

2473 

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

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

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

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

2478 

2479 

2480 .. seealso:: 

2481 

2482 :meth:`_engine.Connection.get_isolation_level` 

2483 - view current level 

2484 

2485 :attr:`_engine.Connection.default_isolation_level` 

2486 - view default level 

2487 

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

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

2490 

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

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

2493 

2494 

2495 """ 

2496 

2497 raise NotImplementedError() 

2498 

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

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

2501 

2502 :param dbapi_connection: a DBAPI connection object 

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

2504 :rtype: bool 

2505 

2506 This method inspects the given DBAPI connection to determine 

2507 whether autocommit mode is currently enabled. The specific 

2508 mechanism for detecting autocommit varies by database dialect 

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

2510 round trips. 

2511 

2512 .. note:: 

2513 

2514 Not all dialects support autocommit detection. Dialects 

2515 that do not support this feature will raise 

2516 :exc:`NotImplementedError`. 

2517 

2518 """ 

2519 raise NotImplementedError( 

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

2521 ) 

2522 

2523 def get_default_isolation_level( 

2524 self, dbapi_conn: DBAPIConnection 

2525 ) -> IsolationLevel: 

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

2527 a default isolation level if one cannot be retrieved. 

2528 

2529 This method may only raise NotImplementedError and 

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

2531 first connect. 

2532 

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

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

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

2536 

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

2538 method unless overridden by a dialect. 

2539 

2540 .. versionadded:: 1.3.22 

2541 

2542 """ 

2543 raise NotImplementedError() 

2544 

2545 def get_isolation_level_values( 

2546 self, dbapi_conn: DBAPIConnection 

2547 ) -> Sequence[IsolationLevel]: 

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

2549 by this dialect. 

2550 

2551 The available names should use the following conventions: 

2552 

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

2554 names but these are normalized into UPPERCASE before being passed 

2555 along to the dialect. 

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

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

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

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

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

2561 ``READ COMMITTED``, ``REPEATABLE READ``, ``SERIALIZABLE`` 

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

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

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

2565 are named in UPPERCASE and use spaces not underscores. 

2566 

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

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

2569 :class:`_exc.ArgumentError`. 

2570 

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

2572 the dialect needs to interrogate the connection itself to determine 

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

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

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

2576 

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

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

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

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

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

2582 not yet be implementing this method. 

2583 

2584 .. versionadded:: 2.0 

2585 

2586 """ 

2587 raise NotImplementedError() 

2588 

2589 def _assert_and_set_isolation_level( 

2590 self, dbapi_conn: DBAPIConnection, level: IsolationLevel 

2591 ) -> None: 

2592 raise NotImplementedError() 

2593 

2594 @classmethod 

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

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

2597 

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

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

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

2601 the actual dialect to be used. 

2602 

2603 By default this just returns the cls. 

2604 

2605 """ 

2606 return cls 

2607 

2608 @classmethod 

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

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

2611 an async engine. 

2612 

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

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

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

2616 ``psycopg`` driver. 

2617 

2618 .. versionadded:: 2 

2619 

2620 .. seealso:: 

2621 

2622 :meth:`.Dialect.get_dialect_cls` 

2623 

2624 """ 

2625 return cls.get_dialect_cls(url) 

2626 

2627 @classmethod 

2628 def load_provisioning(cls) -> None: 

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

2630 

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

2632 provisioning followers, this method should initiate that process. 

2633 

2634 A typical implementation would be:: 

2635 

2636 @classmethod 

2637 def load_provisioning(cls): 

2638 __import__("mydialect.provision") 

2639 

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

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

2642 attribute:: 

2643 

2644 @classmethod 

2645 def load_provisioning(cls): 

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

2647 try: 

2648 __import__(package + ".provision") 

2649 except ImportError: 

2650 pass 

2651 

2652 .. versionadded:: 1.3.14 

2653 

2654 """ 

2655 

2656 @classmethod 

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

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

2659 :class:`_engine.Engine`. 

2660 

2661 If the dialect returned a different class from the 

2662 :meth:`.get_dialect_cls` 

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

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

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

2666 

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

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

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

2670 

2671 """ 

2672 

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

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

2675 package. 

2676 

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

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

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

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

2681 connection-like object as returned by the driver. 

2682 

2683 .. versionadded:: 1.4.24 

2684 

2685 """ 

2686 raise NotImplementedError() 

2687 

2688 def set_engine_execution_options( 

2689 self, engine: Engine, opts: CoreExecuteOptionsParameter 

2690 ) -> None: 

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

2692 

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

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

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

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

2697 connection. 

2698 

2699 """ 

2700 raise NotImplementedError() 

2701 

2702 def set_connection_execution_options( 

2703 self, connection: Connection, opts: CoreExecuteOptionsParameter 

2704 ) -> None: 

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

2706 

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

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

2709 execution option. Dialects can intercept various execution options 

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

2711 

2712 .. versionadded:: 1.4 

2713 

2714 """ 

2715 raise NotImplementedError() 

2716 

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

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

2719 raise NotImplementedError() 

2720 

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

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

2723 

2724 

2725class CreateEnginePlugin: 

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

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

2728 

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

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

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

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

2733 :class:`_engine.CreateEnginePlugin` include: 

2734 

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

2736 number of checkouts and/or time spent with statements 

2737 

2738 * connectivity plugins such as proxies 

2739 

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

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

2742 

2743 

2744 import logging 

2745 

2746 from sqlalchemy.engine import CreateEnginePlugin 

2747 from sqlalchemy import event 

2748 

2749 

2750 class LogCursorEventsPlugin(CreateEnginePlugin): 

2751 def __init__(self, url, kwargs): 

2752 # consume the parameter "log_cursor_logging_name" from the 

2753 # URL query 

2754 logging_name = url.query.get( 

2755 "log_cursor_logging_name", "log_cursor" 

2756 ) 

2757 

2758 self.log = logging.getLogger(logging_name) 

2759 

2760 def update_url(self, url): 

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

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

2763 

2764 def engine_created(self, engine): 

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

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

2767 

2768 def _log_event( 

2769 self, 

2770 conn, 

2771 cursor, 

2772 statement, 

2773 parameters, 

2774 context, 

2775 executemany, 

2776 ): 

2777 

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

2779 

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

2781 of dialects:: 

2782 

2783 entry_points = { 

2784 "sqlalchemy.plugins": [ 

2785 "log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin" 

2786 ] 

2787 } 

2788 

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

2790 URL as in:: 

2791 

2792 from sqlalchemy import create_engine 

2793 

2794 engine = create_engine( 

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

2796 "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger" 

2797 ) 

2798 

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

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

2801 in the URL:: 

2802 

2803 engine = create_engine( 

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

2805 "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three" 

2806 ) 

2807 

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

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

2810 

2811 engine = create_engine( 

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

2813 ) 

2814 

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

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

2817 

2818 A plugin may consume plugin-specific arguments from the 

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

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

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

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

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

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

2825 

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

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

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

2829 should be consumed by implementing the 

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

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

2832 

2833 class MyPlugin(CreateEnginePlugin): 

2834 def __init__(self, url, kwargs): 

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

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

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

2838 

2839 def update_url(self, url): 

2840 return url.difference_update_query( 

2841 ["my_argument_one", "my_argument_two"] 

2842 ) 

2843 

2844 Arguments like those illustrated above would be consumed from a 

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

2846 

2847 from sqlalchemy import create_engine 

2848 

2849 engine = create_engine( 

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

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

2852 my_argument_three="bat", 

2853 ) 

2854 

2855 .. versionchanged:: 1.4 

2856 

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

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

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

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

2861 is invoked after the plugin is constructed. 

2862 

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

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

2865 method to detect which version is running:: 

2866 

2867 class MyPlugin(CreateEnginePlugin): 

2868 def __init__(self, url, kwargs): 

2869 if hasattr(CreateEnginePlugin, "update_url"): 

2870 # detect the 1.4 API 

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

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

2873 else: 

2874 # detect the 1.3 and earlier API - mutate the 

2875 # URL directly 

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

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

2878 

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

2880 

2881 def update_url(self, url): 

2882 # this method is only called in the 1.4 version 

2883 return url.difference_update_query( 

2884 ["my_argument_one", "my_argument_two"] 

2885 ) 

2886 

2887 .. seealso:: 

2888 

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

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

2891 

2892 

2893 When the engine creation process completes and produces the 

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

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

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

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

2898 

2899 """ # noqa: E501 

2900 

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

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

2903 

2904 The plugin object is instantiated individually for each call 

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

2906 Engine` will be 

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

2908 corresponding to this URL. 

2909 

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

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

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

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

2914 

2915 .. versionchanged:: 1.4 

2916 

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

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

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

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

2921 

2922 :param kwargs: The keyword arguments passed to 

2923 :func:`_sa.create_engine`. 

2924 

2925 """ 

2926 self.url = url 

2927 

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

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

2930 

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

2932 typically used to consume configuration arguments from the 

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

2934 recognized by the dialect. The 

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

2936 to remove these arguments. See the docstring at 

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

2938 

2939 

2940 .. versionadded:: 1.4 

2941 

2942 """ 

2943 raise NotImplementedError() 

2944 

2945 def handle_dialect_kwargs( 

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

2947 ) -> None: 

2948 """parse and modify dialect kwargs""" 

2949 

2950 def handle_pool_kwargs( 

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

2952 ) -> None: 

2953 """parse and modify pool kwargs""" 

2954 

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

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

2957 object when it is fully constructed. 

2958 

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

2960 registering engine or connection pool events. 

2961 

2962 """ 

2963 

2964 

2965class ExecutionContext: 

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

2967 execution. 

2968 

2969 """ 

2970 

2971 engine: Engine 

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

2973 

2974 connection: Connection 

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

2976 generators to execute SQL. This Connection should reference the 

2977 same underlying connection/transactional resources of 

2978 root_connection.""" 

2979 

2980 root_connection: Connection 

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

2982 

2983 dialect: Dialect 

2984 """dialect which created this ExecutionContext.""" 

2985 

2986 cursor: DBAPICursor 

2987 """DB-API cursor procured from the connection""" 

2988 

2989 compiled: Optional[Compiled] 

2990 """if passed to constructor, sqlalchemy.engine.base.Compiled object 

2991 being executed""" 

2992 

2993 statement: str 

2994 """string version of the statement to be executed. Is either 

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

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

2997 

2998 invoked_statement: Optional[Executable] 

2999 """The Executable statement object that was given in the first place. 

3000 

3001 This should be structurally equivalent to compiled.statement, but not 

3002 necessarily the same object as in a caching scenario the compiled form 

3003 will have been extracted from the cache. 

3004 

3005 """ 

3006 

3007 parameters: _AnyMultiExecuteParams 

3008 """bind parameters passed to the execute() or exec_driver_sql() methods. 

3009 

3010 These are always stored as a list of parameter entries. A single-element 

3011 list corresponds to a ``cursor.execute()`` call and a multiple-element 

3012 list corresponds to ``cursor.executemany()``, except in the case 

3013 of :attr:`.ExecuteStyle.INSERTMANYVALUES` which will use 

3014 ``cursor.execute()`` one or more times. 

3015 

3016 """ 

3017 

3018 no_parameters: bool 

3019 """True if the execution style does not use parameters""" 

3020 

3021 isinsert: bool 

3022 """True if the statement is an INSERT.""" 

3023 

3024 isupdate: bool 

3025 """True if the statement is an UPDATE.""" 

3026 

3027 execute_style: ExecuteStyle 

3028 """the style of DBAPI cursor method that will be used to execute 

3029 a statement. 

3030 

3031 .. versionadded:: 2.0 

3032 

3033 """ 

3034 

3035 executemany: bool 

3036 """True if the context has a list of more than one parameter set. 

3037 

3038 Historically this attribute links to whether ``cursor.execute()`` or 

3039 ``cursor.executemany()`` will be used. It also can now mean that 

3040 "insertmanyvalues" may be used which indicates one or more 

3041 ``cursor.execute()`` calls. 

3042 

3043 """ 

3044 

3045 prefetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 

3046 """a list of Column objects for which a client-side default 

3047 was fired off. Applies to inserts and updates.""" 

3048 

3049 postfetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 

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

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

3052 and updates.""" 

3053 

3054 execution_options: _ExecuteOptions 

3055 """Execution options associated with the current statement execution""" 

3056 

3057 @classmethod 

3058 def _init_ddl( 

3059 cls, 

3060 dialect: Dialect, 

3061 connection: Connection, 

3062 dbapi_connection: PoolProxiedConnection, 

3063 execution_options: _ExecuteOptions, 

3064 compiled_ddl: DDLCompiler, 

3065 ) -> ExecutionContext: 

3066 raise NotImplementedError() 

3067 

3068 @classmethod 

3069 def _init_compiled( 

3070 cls, 

3071 dialect: Dialect, 

3072 connection: Connection, 

3073 dbapi_connection: PoolProxiedConnection, 

3074 execution_options: _ExecuteOptions, 

3075 compiled: SQLCompiler, 

3076 parameters: _CoreMultiExecuteParams, 

3077 invoked_statement: Executable, 

3078 extracted_parameters: Optional[Sequence[BindParameter[Any]]], 

3079 cache_hit: CacheStats = CacheStats.CACHING_DISABLED, 

3080 ) -> ExecutionContext: 

3081 raise NotImplementedError() 

3082 

3083 @classmethod 

3084 def _init_statement( 

3085 cls, 

3086 dialect: Dialect, 

3087 connection: Connection, 

3088 dbapi_connection: PoolProxiedConnection, 

3089 execution_options: _ExecuteOptions, 

3090 statement: str, 

3091 parameters: _DBAPIMultiExecuteParams, 

3092 ) -> ExecutionContext: 

3093 raise NotImplementedError() 

3094 

3095 @classmethod 

3096 def _init_default( 

3097 cls, 

3098 dialect: Dialect, 

3099 connection: Connection, 

3100 dbapi_connection: PoolProxiedConnection, 

3101 execution_options: _ExecuteOptions, 

3102 ) -> ExecutionContext: 

3103 raise NotImplementedError() 

3104 

3105 def _exec_default( 

3106 self, 

3107 column: Optional[Column[Any]], 

3108 default: DefaultGenerator, 

3109 type_: Optional[TypeEngine[Any]], 

3110 ) -> Any: 

3111 raise NotImplementedError() 

3112 

3113 def _prepare_set_input_sizes( 

3114 self, 

3115 ) -> Optional[List[Tuple[str, Any, TypeEngine[Any]]]]: 

3116 raise NotImplementedError() 

3117 

3118 def _get_cache_stats(self) -> str: 

3119 raise NotImplementedError() 

3120 

3121 def _setup_result_proxy(self) -> CursorResult[Any]: 

3122 raise NotImplementedError() 

3123 

3124 def fire_sequence(self, seq: Sequence_SchemaItem, type_: Integer) -> int: 

3125 """given a :class:`.Sequence`, invoke it and return the next int 

3126 value""" 

3127 raise NotImplementedError() 

3128 

3129 def create_cursor(self) -> DBAPICursor: 

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

3131 connection. 

3132 

3133 Some dialects may wish to change the behavior of 

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

3135 "server side" cursor. 

3136 """ 

3137 

3138 raise NotImplementedError() 

3139 

3140 def pre_exec(self) -> None: 

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

3142 

3143 If a compiled statement was passed to this ExecutionContext, 

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

3145 initialized after this statement is complete. 

3146 """ 

3147 

3148 raise NotImplementedError() 

3149 

3150 def get_out_parameter_values( 

3151 self, out_param_names: Sequence[str] 

3152 ) -> Sequence[Any]: 

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

3154 

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

3156 when there is a :class:`.SQLCompiler` object which has the 

3157 :attr:`.SQLCompiler.has_out_parameters` flag set. This flag in turn 

3158 will be set to True if the statement itself has :class:`.BindParameter` 

3159 objects that have the ``.isoutparam`` flag set which are consumed by 

3160 the :meth:`.SQLCompiler.visit_bindparam` method. If the dialect 

3161 compiler produces :class:`.BindParameter` objects with ``.isoutparam`` 

3162 set which are not handled by :meth:`.SQLCompiler.visit_bindparam`, it 

3163 should set this flag explicitly. 

3164 

3165 The list of names that were rendered for each bound parameter 

3166 is passed to the method. The method should then return a sequence of 

3167 values corresponding to the list of parameter objects. Unlike in 

3168 previous SQLAlchemy versions, the values can be the **raw values** from 

3169 the DBAPI; the execution context will apply the appropriate type 

3170 handler based on what's present in self.compiled.binds and update the 

3171 values. The processed dictionary will then be made available via the 

3172 ``.out_parameters`` collection on the result object. Note that 

3173 SQLAlchemy 1.4 has multiple kinds of result object as part of the 2.0 

3174 transition. 

3175 

3176 .. versionadded:: 1.4 - added 

3177 :meth:`.ExecutionContext.get_out_parameter_values`, which is invoked 

3178 automatically by the :class:`.DefaultExecutionContext` when there 

3179 are :class:`.BindParameter` objects with the ``.isoutparam`` flag 

3180 set. This replaces the practice of setting out parameters within 

3181 the now-removed ``get_result_proxy()`` method. 

3182 

3183 """ 

3184 raise NotImplementedError() 

3185 

3186 def post_exec(self) -> None: 

3187 """Called after the execution of a compiled statement. 

3188 

3189 If a compiled statement was passed to this ExecutionContext, 

3190 the `last_insert_ids`, `last_inserted_params`, etc. 

3191 datamembers should be available after this method completes. 

3192 """ 

3193 

3194 raise NotImplementedError() 

3195 

3196 def handle_dbapi_exception(self, e: BaseException) -> None: 

3197 """Receive a DBAPI exception which occurred upon execute, result 

3198 fetch, etc.""" 

3199 

3200 raise NotImplementedError() 

3201 

3202 def lastrow_has_defaults(self) -> bool: 

3203 """Return True if the last INSERT or UPDATE row contained 

3204 inlined or database-side defaults. 

3205 """ 

3206 

3207 raise NotImplementedError() 

3208 

3209 def get_rowcount(self) -> Optional[int]: 

3210 """Return the DBAPI ``cursor.rowcount`` value, or in some 

3211 cases an interpreted value. 

3212 

3213 See :attr:`_engine.CursorResult.rowcount` for details on this. 

3214 

3215 """ 

3216 

3217 raise NotImplementedError() 

3218 

3219 def fetchall_for_returning(self, cursor: DBAPICursor) -> Sequence[Any]: 

3220 """For a RETURNING result, deliver cursor.fetchall() from the 

3221 DBAPI cursor. 

3222 

3223 This is a dialect-specific hook for dialects that have special 

3224 considerations when calling upon the rows delivered for a 

3225 "RETURNING" statement. Default implementation is 

3226 ``cursor.fetchall()``. 

3227 

3228 This hook is currently used only by the :term:`insertmanyvalues` 

3229 feature. Dialects that don't set ``use_insertmanyvalues=True`` 

3230 don't need to consider this hook. 

3231 

3232 .. versionadded:: 2.0.10 

3233 

3234 """ 

3235 raise NotImplementedError() 

3236 

3237 

3238class ConnectionEventsTarget(EventTarget): 

3239 """An object which can accept events from :class:`.ConnectionEvents`. 

3240 

3241 Includes :class:`_engine.Connection` and :class:`_engine.Engine`. 

3242 

3243 .. versionadded:: 2.0 

3244 

3245 """ 

3246 

3247 dispatch: dispatcher[ConnectionEventsTarget] 

3248 

3249 

3250Connectable = ConnectionEventsTarget 

3251 

3252 

3253class ExceptionContext: 

3254 """Encapsulate information about an error condition in progress. 

3255 

3256 This object exists solely to be passed to the 

3257 :meth:`_events.DialectEvents.handle_error` event, 

3258 supporting an interface that 

3259 can be extended without backwards-incompatibility. 

3260 

3261 

3262 """ 

3263 

3264 __slots__ = () 

3265 

3266 dialect: Dialect 

3267 """The :class:`_engine.Dialect` in use. 

3268 

3269 This member is present for all invocations of the event hook. 

3270 

3271 .. versionadded:: 2.0 

3272 

3273 """ 

3274 

3275 connection: Optional[Connection] 

3276 """The :class:`_engine.Connection` in use during the exception. 

3277 

3278 This member is present, except in the case of a failure when 

3279 first connecting. 

3280 

3281 .. seealso:: 

3282 

3283 :attr:`.ExceptionContext.engine` 

3284 

3285 

3286 """ 

3287 

3288 engine: Optional[Engine] 

3289 """The :class:`_engine.Engine` in use during the exception. 

3290 

3291 This member is present in all cases except for when handling an error 

3292 within the connection pool "pre-ping" process. 

3293 

3294 """ 

3295 

3296 cursor: Optional[DBAPICursor] 

3297 """The DBAPI cursor object. 

3298 

3299 May be None. 

3300 

3301 """ 

3302 

3303 statement: Optional[str] 

3304 """String SQL statement that was emitted directly to the DBAPI. 

3305 

3306 May be None. 

3307 

3308 """ 

3309 

3310 parameters: Optional[_DBAPIAnyExecuteParams] 

3311 """Parameter collection that was emitted directly to the DBAPI. 

3312 

3313 May be None. 

3314 

3315 """ 

3316 

3317 original_exception: BaseException 

3318 """The exception object which was caught. 

3319 

3320 This member is always present. 

3321 

3322 """ 

3323 

3324 sqlalchemy_exception: Optional[StatementError] 

3325 """The :class:`sqlalchemy.exc.StatementError` which wraps the original, 

3326 and will be raised if exception handling is not circumvented by the event. 

3327 

3328 May be None, as not all exception types are wrapped by SQLAlchemy. 

3329 For DBAPI-level exceptions that subclass the dbapi's Error class, this 

3330 field will always be present. 

3331 

3332 """ 

3333 

3334 chained_exception: Optional[BaseException] 

3335 """The exception that was returned by the previous handler in the 

3336 exception chain, if any. 

3337 

3338 If present, this exception will be the one ultimately raised by 

3339 SQLAlchemy unless a subsequent handler replaces it. 

3340 

3341 May be None. 

3342 

3343 """ 

3344 

3345 execution_context: Optional[ExecutionContext] 

3346 """The :class:`.ExecutionContext` corresponding to the execution 

3347 operation in progress. 

3348 

3349 This is present for statement execution operations, but not for 

3350 operations such as transaction begin/end. It also is not present when 

3351 the exception was raised before the :class:`.ExecutionContext` 

3352 could be constructed. 

3353 

3354 Note that the :attr:`.ExceptionContext.statement` and 

3355 :attr:`.ExceptionContext.parameters` members may represent a 

3356 different value than that of the :class:`.ExecutionContext`, 

3357 potentially in the case where a 

3358 :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar 

3359 modified the statement/parameters to be sent. 

3360 

3361 May be None. 

3362 

3363 """ 

3364 

3365 is_disconnect: bool 

3366 """Represent whether the exception as occurred represents a "disconnect" 

3367 condition. 

3368 

3369 This flag will always be True or False within the scope of the 

3370 :meth:`_events.DialectEvents.handle_error` handler. 

3371 

3372 SQLAlchemy will defer to this flag in order to determine whether or not 

3373 the connection should be invalidated subsequently. That is, by 

3374 assigning to this flag, a "disconnect" event which then results in 

3375 a connection and pool invalidation can be invoked or prevented by 

3376 changing this flag. 

3377 

3378 

3379 .. note:: The pool "pre_ping" handler enabled using the 

3380 :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not** 

3381 consult this event before deciding if the "ping" returned false, 

3382 as opposed to receiving an unhandled error. For this use case, the 

3383 :ref:`legacy recipe based on engine_connect() may be used 

3384 <pool_disconnects_pessimistic_custom>`. A future API allow more 

3385 comprehensive customization of the "disconnect" detection mechanism 

3386 across all functions. 

3387 

3388 """ 

3389 

3390 invalidate_pool_on_disconnect: bool 

3391 """Represent whether all connections in the pool should be invalidated 

3392 when a "disconnect" condition is in effect. 

3393 

3394 Setting this flag to False within the scope of the 

3395 :meth:`_events.DialectEvents.handle_error` 

3396 event will have the effect such 

3397 that the full collection of connections in the pool will not be 

3398 invalidated during a disconnect; only the current connection that is the 

3399 subject of the error will actually be invalidated. 

3400 

3401 The purpose of this flag is for custom disconnect-handling schemes where 

3402 the invalidation of other connections in the pool is to be performed 

3403 based on other conditions, or even on a per-connection basis. 

3404 

3405 """ 

3406 

3407 is_pre_ping: bool 

3408 """Indicates if this error is occurring within the "pre-ping" step 

3409 performed when :paramref:`_sa.create_engine.pool_pre_ping` is set to 

3410 ``True``. In this mode, the :attr:`.ExceptionContext.engine` attribute 

3411 will be ``None``. The dialect in use is accessible via the 

3412 :attr:`.ExceptionContext.dialect` attribute. 

3413 

3414 .. versionadded:: 2.0.5 

3415 

3416 """ 

3417 

3418 

3419class AdaptedConnection: 

3420 """Interface of an adapted connection object to support the DBAPI protocol. 

3421 

3422 Used by asyncio dialects to provide a sync-style pep-249 facade on top 

3423 of the asyncio connection/cursor API provided by the driver. 

3424 

3425 .. versionadded:: 1.4.24 

3426 

3427 """ 

3428 

3429 __slots__ = ("_connection",) 

3430 

3431 _connection: AsyncIODBAPIConnection 

3432 

3433 @property 

3434 def driver_connection(self) -> Any: 

3435 """The connection object as returned by the driver after a connect.""" 

3436 return self._connection 

3437 

3438 def run_async(self, fn: Callable[[Any], Awaitable[_T]]) -> _T: 

3439 """Run the awaitable returned by the given function, which is passed 

3440 the raw asyncio driver connection. 

3441 

3442 This is used to invoke awaitable-only methods on the driver connection 

3443 within the context of a "synchronous" method, like a connection 

3444 pool event handler. 

3445 

3446 E.g.:: 

3447 

3448 engine = create_async_engine(...) 

3449 

3450 

3451 @event.listens_for(engine.sync_engine, "connect") 

3452 def register_custom_types( 

3453 dbapi_connection, # ... 

3454 ): 

3455 dbapi_connection.run_async( 

3456 lambda connection: connection.set_type_codec( 

3457 "MyCustomType", encoder, decoder, ... 

3458 ) 

3459 ) 

3460 

3461 .. versionadded:: 1.4.30 

3462 

3463 .. seealso:: 

3464 

3465 :ref:`asyncio_events_run_async` 

3466 

3467 """ 

3468 return await_only(fn(self._connection)) 

3469 

3470 def __repr__(self) -> str: 

3471 return "<AdaptedConnection %s>" % self._connection