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