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 Protocol
26from typing import Sequence
27from typing import Set
28from typing import Tuple
29from typing import Type
30from typing import TYPE_CHECKING
31from typing import TypedDict
32from typing import TypeVar
33from typing import Union
34
35from .. import util
36from ..event import EventTarget
37from ..pool import Pool
38from ..pool import PoolProxiedConnection as PoolProxiedConnection
39from ..sql.compiler import Compiled as Compiled
40from ..sql.compiler import Compiled # noqa
41from ..sql.compiler import TypeCompiler as TypeCompiler
42from ..sql.compiler import TypeCompiler # noqa
43from ..util import immutabledict
44from ..util.concurrency import await_
45from ..util.typing import Literal
46from ..util.typing import NotRequired
47
48if TYPE_CHECKING:
49 from .base import Connection
50 from .base import Engine
51 from .cursor import CursorResult
52 from .url import URL
53 from ..connectors.asyncio import AsyncIODBAPIConnection
54 from ..event import _ListenerFnType
55 from ..event import dispatcher
56 from ..exc import StatementError
57 from ..sql import Executable
58 from ..sql.compiler import _InsertManyValuesBatch
59 from ..sql.compiler import 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 driver_column_names: bool
294
295
296_ExecuteOptions = immutabledict[str, Any]
297CoreExecuteOptionsParameter = Union[
298 _CoreKnownExecutionOptions, Mapping[str, Any]
299]
300
301
302class ReflectedIdentity(TypedDict):
303 """represent the reflected IDENTITY structure of a column, corresponding
304 to the :class:`_schema.Identity` construct.
305
306 The :class:`.ReflectedIdentity` structure is part of the
307 :class:`.ReflectedColumn` structure, which is returned by the
308 :meth:`.Inspector.get_columns` method.
309
310 """
311
312 always: bool
313 """type of identity column"""
314
315 on_null: bool
316 """indicates ON NULL"""
317
318 start: int
319 """starting index of the sequence"""
320
321 increment: int
322 """increment value of the sequence"""
323
324 minvalue: int
325 """the minimum value of the sequence."""
326
327 maxvalue: int
328 """the maximum value of the sequence."""
329
330 nominvalue: bool
331 """no minimum value of the sequence."""
332
333 nomaxvalue: bool
334 """no maximum value of the sequence."""
335
336 cycle: bool
337 """allows the sequence to wrap around when the maxvalue
338 or minvalue has been reached."""
339
340 cache: Optional[int]
341 """number of future values in the
342 sequence which are calculated in advance."""
343
344 order: bool
345 """if true, renders the ORDER keyword."""
346
347
348class ReflectedComputed(TypedDict):
349 """Represent the reflected elements of a computed column, corresponding
350 to the :class:`_schema.Computed` construct.
351
352 The :class:`.ReflectedComputed` structure is part of the
353 :class:`.ReflectedColumn` structure, which is returned by the
354 :meth:`.Inspector.get_columns` method.
355
356 """
357
358 sqltext: str
359 """the expression used to generate this column returned
360 as a string SQL expression"""
361
362 persisted: NotRequired[bool]
363 """indicates if the value is stored in the table or computed on demand"""
364
365
366class ReflectedColumn(TypedDict):
367 """Dictionary representing the reflected elements corresponding to
368 a :class:`_schema.Column` object.
369
370 The :class:`.ReflectedColumn` structure is returned by the
371 :class:`.Inspector.get_columns` method.
372
373 """
374
375 name: str
376 """column name"""
377
378 type: TypeEngine[Any]
379 """column type represented as a :class:`.TypeEngine` instance."""
380
381 nullable: bool
382 """boolean flag if the column is NULL or NOT NULL"""
383
384 default: Optional[str]
385 """column default expression as a SQL string"""
386
387 autoincrement: NotRequired[bool]
388 """database-dependent autoincrement flag.
389
390 This flag indicates if the column has a database-side "autoincrement"
391 flag of some kind. Within SQLAlchemy, other kinds of columns may
392 also act as an "autoincrement" column without necessarily having
393 such a flag on them.
394
395 See :paramref:`_schema.Column.autoincrement` for more background on
396 "autoincrement".
397
398 """
399
400 comment: NotRequired[Optional[str]]
401 """comment for the column, if present.
402 Only some dialects return this key
403 """
404
405 computed: NotRequired[ReflectedComputed]
406 """indicates that this column is computed by the database.
407 Only some dialects return this key.
408 """
409
410 identity: NotRequired[ReflectedIdentity]
411 """indicates this column is an IDENTITY column.
412 Only some dialects return this key.
413
414 .. versionadded:: 1.4 - added support for identity column reflection.
415 """
416
417 dialect_options: NotRequired[Dict[str, Any]]
418 """Additional dialect-specific options detected for this reflected
419 object"""
420
421
422class ReflectedConstraint(TypedDict):
423 """Dictionary representing the reflected elements corresponding to
424 :class:`.Constraint`
425
426 A base class for all constraints
427 """
428
429 name: Optional[str]
430 """constraint name"""
431
432 comment: NotRequired[Optional[str]]
433 """comment for the constraint, if present"""
434
435
436class ReflectedCheckConstraint(ReflectedConstraint):
437 """Dictionary representing the reflected elements corresponding to
438 :class:`.CheckConstraint`.
439
440 The :class:`.ReflectedCheckConstraint` structure is returned by the
441 :meth:`.Inspector.get_check_constraints` method.
442
443 """
444
445 sqltext: str
446 """the check constraint's SQL expression"""
447
448 dialect_options: NotRequired[Dict[str, Any]]
449 """Additional dialect-specific options detected for this check constraint
450 """
451
452
453class ReflectedUniqueConstraint(ReflectedConstraint):
454 """Dictionary representing the reflected elements corresponding to
455 :class:`.UniqueConstraint`.
456
457 The :class:`.ReflectedUniqueConstraint` structure is returned by the
458 :meth:`.Inspector.get_unique_constraints` method.
459
460 """
461
462 column_names: List[str]
463 """column names which comprise the unique constraint"""
464
465 duplicates_index: NotRequired[Optional[str]]
466 "Indicates if this unique constraint duplicates an index with this name"
467
468 dialect_options: NotRequired[Dict[str, Any]]
469 """Additional dialect-specific options detected for this unique
470 constraint"""
471
472
473class ReflectedPrimaryKeyConstraint(ReflectedConstraint):
474 """Dictionary representing the reflected elements corresponding to
475 :class:`.PrimaryKeyConstraint`.
476
477 The :class:`.ReflectedPrimaryKeyConstraint` structure is returned by the
478 :meth:`.Inspector.get_pk_constraint` method.
479
480 """
481
482 constrained_columns: List[str]
483 """column names which comprise the primary key"""
484
485 dialect_options: NotRequired[Dict[str, Any]]
486 """Additional dialect-specific options detected for this primary key"""
487
488
489class ReflectedForeignKeyConstraint(ReflectedConstraint):
490 """Dictionary representing the reflected elements corresponding to
491 :class:`.ForeignKeyConstraint`.
492
493 The :class:`.ReflectedForeignKeyConstraint` structure is returned by
494 the :meth:`.Inspector.get_foreign_keys` method.
495
496 """
497
498 constrained_columns: List[str]
499 """local column names which comprise the foreign key"""
500
501 referred_schema: Optional[str]
502 """schema name of the table being referred"""
503
504 referred_table: str
505 """name of the table being referred"""
506
507 referred_columns: List[str]
508 """referred column names that correspond to ``constrained_columns``"""
509
510 options: NotRequired[Dict[str, Any]]
511 """Additional options detected for this foreign key constraint"""
512
513
514class ReflectedIndex(TypedDict):
515 """Dictionary representing the reflected elements corresponding to
516 :class:`.Index`.
517
518 The :class:`.ReflectedIndex` structure is returned by the
519 :meth:`.Inspector.get_indexes` method.
520
521 """
522
523 name: Optional[str]
524 """index name"""
525
526 column_names: List[Optional[str]]
527 """column names which the index references.
528 An element of this list is ``None`` if it's an expression and is
529 returned in the ``expressions`` list.
530 """
531
532 expressions: NotRequired[List[str]]
533 """Expressions that compose the index. This list, when present, contains
534 both plain column names (that are also in ``column_names``) and
535 expressions (that are ``None`` in ``column_names``).
536 """
537
538 unique: bool
539 """whether or not the index has a unique flag"""
540
541 duplicates_constraint: NotRequired[Optional[str]]
542 "Indicates if this index mirrors a constraint with this name"
543
544 include_columns: NotRequired[List[str]]
545 """columns to include in the INCLUDE clause for supporting databases.
546
547 .. deprecated:: 2.0
548
549 Legacy value, will be replaced with
550 ``index_dict["dialect_options"]["<dialect name>_include"]``
551
552 """
553
554 column_sorting: NotRequired[Dict[str, Tuple[str]]]
555 """optional dict mapping column names or expressions to tuple of sort
556 keywords, which may include ``asc``, ``desc``, ``nulls_first``,
557 ``nulls_last``.
558 """
559
560 dialect_options: NotRequired[Dict[str, Any]]
561 """Additional dialect-specific options detected for this index"""
562
563
564class ReflectedTableComment(TypedDict):
565 """Dictionary representing the reflected comment corresponding to
566 the :attr:`_schema.Table.comment` attribute.
567
568 The :class:`.ReflectedTableComment` structure is returned by the
569 :meth:`.Inspector.get_table_comment` method.
570
571 """
572
573 text: Optional[str]
574 """text of the comment"""
575
576
577class BindTyping(Enum):
578 """Define different methods of passing typing information for
579 bound parameters in a statement to the database driver.
580
581 .. versionadded:: 2.0
582
583 """
584
585 NONE = 1
586 """No steps are taken to pass typing information to the database driver.
587
588 This is the default behavior for databases such as SQLite, MySQL / MariaDB,
589 SQL Server.
590
591 """
592
593 SETINPUTSIZES = 2
594 """Use the pep-249 setinputsizes method.
595
596 This is only implemented for DBAPIs that support this method and for which
597 the SQLAlchemy dialect has the appropriate infrastructure for that dialect
598 set up. Current dialects include python-oracledb, cx_Oracle as well as
599 optional support for SQL Server using pyodbc.
600
601 When using setinputsizes, dialects also have a means of only using the
602 method for certain datatypes using include/exclude lists.
603
604 When SETINPUTSIZES is used, the :meth:`.Dialect.do_set_input_sizes` method
605 is called for each statement executed which has bound parameters.
606
607 """
608
609 RENDER_CASTS = 3
610 """Render casts or other directives in the SQL string.
611
612 This method is used for all PostgreSQL dialects, including asyncpg,
613 pg8000, psycopg, psycopg2. Dialects which implement this can choose
614 which kinds of datatypes are explicitly cast in SQL statements and which
615 aren't.
616
617 When RENDER_CASTS is used, the compiler will invoke the
618 :meth:`.SQLCompiler.render_bind_cast` method for the rendered
619 string representation of each :class:`.BindParameter` object whose
620 dialect-level type sets the :attr:`.TypeEngine.render_bind_cast` attribute.
621
622 The :meth:`.SQLCompiler.render_bind_cast` is also used to render casts
623 for one form of "insertmanyvalues" query, when both
624 :attr:`.InsertmanyvaluesSentinelOpts.USE_INSERT_FROM_SELECT` and
625 :attr:`.InsertmanyvaluesSentinelOpts.RENDER_SELECT_COL_CASTS` are set,
626 where the casts are applied to the intermediary columns e.g.
627 "INSERT INTO t (a, b, c) SELECT p0::TYP, p1::TYP, p2::TYP "
628 "FROM (VALUES (?, ?), (?, ?), ...)".
629
630 .. versionadded:: 2.0.10 - :meth:`.SQLCompiler.render_bind_cast` is now
631 used within some elements of the "insertmanyvalues" implementation.
632
633
634 """
635
636
637VersionInfoType = Tuple[Union[int, str], ...]
638TableKey = Tuple[Optional[str], str]
639
640
641class Dialect(EventTarget):
642 """Define the behavior of a specific database and DB-API combination.
643
644 Any aspect of metadata definition, SQL query generation,
645 execution, result-set handling, or anything else which varies
646 between databases is defined under the general category of the
647 Dialect. The Dialect acts as a factory for other
648 database-specific object implementations including
649 ExecutionContext, Compiled, DefaultGenerator, and TypeEngine.
650
651 .. note:: Third party dialects should not subclass :class:`.Dialect`
652 directly. Instead, subclass :class:`.default.DefaultDialect` or
653 descendant class.
654
655 """
656
657 CACHE_HIT = CacheStats.CACHE_HIT
658 CACHE_MISS = CacheStats.CACHE_MISS
659 CACHING_DISABLED = CacheStats.CACHING_DISABLED
660 NO_CACHE_KEY = CacheStats.NO_CACHE_KEY
661 NO_DIALECT_SUPPORT = CacheStats.NO_DIALECT_SUPPORT
662
663 dispatch: dispatcher[Dialect]
664
665 name: str
666 """identifying name for the dialect from a DBAPI-neutral point of view
667 (i.e. 'sqlite')
668 """
669
670 driver: str
671 """identifying name for the dialect's DBAPI"""
672
673 dialect_description: str
674
675 dbapi: Optional[DBAPIModule]
676 """A reference to the DBAPI module object itself.
677
678 SQLAlchemy dialects import DBAPI modules using the classmethod
679 :meth:`.Dialect.import_dbapi`. The rationale is so that any dialect
680 module can be imported and used to generate SQL statements without the
681 need for the actual DBAPI driver to be installed. Only when an
682 :class:`.Engine` is constructed using :func:`.create_engine` does the
683 DBAPI get imported; at that point, the creation process will assign
684 the DBAPI module to this attribute.
685
686 Dialects should therefore implement :meth:`.Dialect.import_dbapi`
687 which will import the necessary module and return it, and then refer
688 to ``self.dbapi`` in dialect code in order to refer to the DBAPI module
689 contents.
690
691 .. versionchanged:: The :attr:`.Dialect.dbapi` attribute is exclusively
692 used as the per-:class:`.Dialect`-instance reference to the DBAPI
693 module. The previous not-fully-documented ``.Dialect.dbapi()``
694 classmethod is deprecated and replaced by :meth:`.Dialect.import_dbapi`.
695
696 """
697
698 @util.non_memoized_property
699 def loaded_dbapi(self) -> DBAPIModule:
700 """same as .dbapi, but is never None; will raise an error if no
701 DBAPI was set up.
702
703 .. versionadded:: 2.0
704
705 """
706 raise NotImplementedError()
707
708 positional: bool
709 """True if the paramstyle for this Dialect is positional."""
710
711 paramstyle: str
712 """the paramstyle to be used (some DB-APIs support multiple
713 paramstyles).
714 """
715
716 compiler_linting: Linting
717
718 statement_compiler: Type[SQLCompiler]
719 """a :class:`.Compiled` class used to compile SQL statements"""
720
721 ddl_compiler: Type[DDLCompiler]
722 """a :class:`.Compiled` class used to compile DDL statements"""
723
724 type_compiler_cls: ClassVar[Type[TypeCompiler]]
725 """a :class:`.Compiled` class used to compile SQL type objects
726
727 .. versionadded:: 2.0
728
729 """
730
731 type_compiler_instance: TypeCompiler
732 """instance of a :class:`.Compiled` class used to compile SQL type
733 objects
734
735 .. versionadded:: 2.0
736
737 """
738
739 type_compiler: Any
740 """legacy; this is a TypeCompiler class at the class level, a
741 TypeCompiler instance at the instance level.
742
743 Refer to type_compiler_instance instead.
744
745 """
746
747 preparer: Type[IdentifierPreparer]
748 """a :class:`.IdentifierPreparer` class used to
749 quote identifiers.
750 """
751
752 identifier_preparer: IdentifierPreparer
753 """This element will refer to an instance of :class:`.IdentifierPreparer`
754 once a :class:`.DefaultDialect` has been constructed.
755
756 """
757
758 server_version_info: Optional[Tuple[Any, ...]]
759 """a tuple containing a version number for the DB backend in use.
760
761 This value is only available for supporting dialects, and is
762 typically populated during the initial connection to the database.
763 """
764
765 default_schema_name: Optional[str]
766 """the name of the default schema. This value is only available for
767 supporting dialects, and is typically populated during the
768 initial connection to the database.
769
770 """
771
772 # NOTE: this does not take into effect engine-level isolation level.
773 # not clear if this should be changed, seems like it should
774 default_isolation_level: Optional[IsolationLevel]
775 """the isolation that is implicitly present on new connections"""
776
777 skip_autocommit_rollback: bool
778 """Whether or not the :paramref:`.create_engine.skip_autocommit_rollback`
779 parameter was set.
780
781 .. versionadded:: 2.0.43
782
783 """
784
785 # create_engine() -> isolation_level currently goes here
786 _on_connect_isolation_level: Optional[IsolationLevel]
787
788 execution_ctx_cls: Type[ExecutionContext]
789 """a :class:`.ExecutionContext` class used to handle statement execution"""
790
791 execute_sequence_format: Union[
792 Type[Tuple[Any, ...]], Type[Tuple[List[Any]]]
793 ]
794 """either the 'tuple' or 'list' type, depending on what cursor.execute()
795 accepts for the second argument (they vary)."""
796
797 supports_alter: bool
798 """``True`` if the database supports ``ALTER TABLE`` - used only for
799 generating foreign key constraints in certain circumstances
800 """
801
802 max_identifier_length: int
803 """The maximum length of identifier names."""
804 max_index_name_length: Optional[int]
805 """The maximum length of index names if different from
806 ``max_identifier_length``."""
807 max_constraint_name_length: Optional[int]
808 """The maximum length of constraint names if different from
809 ``max_identifier_length``."""
810
811 supports_server_side_cursors: Union[generic_fn_descriptor[bool], bool]
812 """indicates if the dialect supports server side cursors"""
813
814 server_side_cursors: bool
815 """deprecated; indicates if the dialect should attempt to use server
816 side cursors by default"""
817
818 supports_sane_rowcount: bool
819 """Indicate whether the dialect properly implements rowcount for
820 ``UPDATE`` and ``DELETE`` statements.
821 """
822
823 supports_sane_multi_rowcount: bool
824 """Indicate whether the dialect properly implements rowcount for
825 ``UPDATE`` and ``DELETE`` statements when executed via
826 executemany.
827 """
828
829 supports_empty_insert: bool
830 """dialect supports INSERT () VALUES (), i.e. a plain INSERT with no
831 columns in it.
832
833 This is not usually supported; an "empty" insert is typically
834 suited using either "INSERT..DEFAULT VALUES" or
835 "INSERT ... (col) VALUES (DEFAULT)".
836
837 """
838
839 supports_default_values: bool
840 """dialect supports INSERT... DEFAULT VALUES syntax"""
841
842 supports_default_metavalue: bool
843 """dialect supports INSERT...(col) VALUES (DEFAULT) syntax.
844
845 Most databases support this in some way, e.g. SQLite supports it using
846 ``VALUES (NULL)``. MS SQL Server supports the syntax also however
847 is the only included dialect where we have this disabled, as
848 MSSQL does not support the field for the IDENTITY column, which is
849 usually where we like to make use of the feature.
850
851 """
852
853 default_metavalue_token: str = "DEFAULT"
854 """for INSERT... VALUES (DEFAULT) syntax, the token to put in the
855 parenthesis.
856
857 E.g. for SQLite this is the keyword "NULL".
858
859 """
860
861 supports_multivalues_insert: bool
862 """Target database supports INSERT...VALUES with multiple value
863 sets, i.e. INSERT INTO table (cols) VALUES (...), (...), (...), ...
864
865 """
866
867 insert_executemany_returning: bool
868 """dialect / driver / database supports some means of providing
869 INSERT...RETURNING support when dialect.do_executemany() is used.
870
871 """
872
873 insert_executemany_returning_sort_by_parameter_order: bool
874 """dialect / driver / database supports some means of providing
875 INSERT...RETURNING support when dialect.do_executemany() is used
876 along with the :paramref:`_dml.Insert.returning.sort_by_parameter_order`
877 parameter being set.
878
879 """
880
881 update_executemany_returning: bool
882 """dialect supports UPDATE..RETURNING with executemany."""
883
884 delete_executemany_returning: bool
885 """dialect supports DELETE..RETURNING with executemany."""
886
887 use_insertmanyvalues: bool
888 """if True, indicates "insertmanyvalues" functionality should be used
889 to allow for ``insert_executemany_returning`` behavior, if possible.
890
891 In practice, setting this to True means:
892
893 if ``supports_multivalues_insert``, ``insert_returning`` and
894 ``use_insertmanyvalues`` are all True, the SQL compiler will produce
895 an INSERT that will be interpreted by the :class:`.DefaultDialect`
896 as an :attr:`.ExecuteStyle.INSERTMANYVALUES` execution that allows
897 for INSERT of many rows with RETURNING by rewriting a single-row
898 INSERT statement to have multiple VALUES clauses, also executing
899 the statement multiple times for a series of batches when large numbers
900 of rows are given.
901
902 The parameter is False for the default dialect, and is set to True for
903 SQLAlchemy internal dialects SQLite, MySQL/MariaDB, PostgreSQL, SQL Server.
904 It remains at False for Oracle Database, which provides native "executemany
905 with RETURNING" support and also does not support
906 ``supports_multivalues_insert``. For MySQL/MariaDB, those MySQL dialects
907 that don't support RETURNING will not report
908 ``insert_executemany_returning`` as True.
909
910 .. versionadded:: 2.0
911
912 .. seealso::
913
914 :ref:`engine_insertmanyvalues`
915
916 """
917
918 use_insertmanyvalues_wo_returning: bool
919 """if True, and use_insertmanyvalues is also True, INSERT statements
920 that don't include RETURNING will also use "insertmanyvalues".
921
922 .. versionadded:: 2.0
923
924 .. seealso::
925
926 :ref:`engine_insertmanyvalues`
927
928 """
929
930 insertmanyvalues_implicit_sentinel: InsertmanyvaluesSentinelOpts
931 """Options indicating the database supports a form of bulk INSERT where
932 the autoincrement integer primary key can be reliably used as an ordering
933 for INSERTed rows.
934
935 .. versionadded:: 2.0.10
936
937 .. seealso::
938
939 :ref:`engine_insertmanyvalues_returning_order`
940
941 """
942
943 insertmanyvalues_page_size: int
944 """Number of rows to render into an individual INSERT..VALUES() statement
945 for :attr:`.ExecuteStyle.INSERTMANYVALUES` executions.
946
947 The default dialect defaults this to 1000.
948
949 .. versionadded:: 2.0
950
951 .. seealso::
952
953 :paramref:`_engine.Connection.execution_options.insertmanyvalues_page_size` -
954 execution option available on :class:`_engine.Connection`, statements
955
956 """ # noqa: E501
957
958 insertmanyvalues_max_parameters: int
959 """Alternate to insertmanyvalues_page_size, will additionally limit
960 page size based on number of parameters total in the statement.
961
962
963 """
964
965 preexecute_autoincrement_sequences: bool
966 """True if 'implicit' primary key functions must be executed separately
967 in order to get their value, if RETURNING is not used.
968
969 This is currently oriented towards PostgreSQL when the
970 ``implicit_returning=False`` parameter is used on a :class:`.Table`
971 object.
972
973 """
974
975 insert_returning: bool
976 """if the dialect supports RETURNING with INSERT
977
978 .. versionadded:: 2.0
979
980 """
981
982 update_returning: bool
983 """if the dialect supports RETURNING with UPDATE
984
985 .. versionadded:: 2.0
986
987 """
988
989 update_returning_multifrom: bool
990 """if the dialect supports RETURNING with UPDATE..FROM
991
992 .. versionadded:: 2.0
993
994 """
995
996 delete_returning: bool
997 """if the dialect supports RETURNING with DELETE
998
999 .. versionadded:: 2.0
1000
1001 """
1002
1003 delete_returning_multifrom: bool
1004 """if the dialect supports RETURNING with DELETE..FROM
1005
1006 .. versionadded:: 2.0
1007
1008 """
1009
1010 favor_returning_over_lastrowid: bool
1011 """for backends that support both a lastrowid and a RETURNING insert
1012 strategy, favor RETURNING for simple single-int pk inserts.
1013
1014 cursor.lastrowid tends to be more performant on most backends.
1015
1016 """
1017
1018 supports_identity_columns: bool
1019 """target database supports IDENTITY"""
1020
1021 cte_follows_insert: bool
1022 """target database, when given a CTE with an INSERT statement, needs
1023 the CTE to be below the INSERT"""
1024
1025 colspecs: MutableMapping[Type[TypeEngine[Any]], Type[TypeEngine[Any]]]
1026 """A dictionary of TypeEngine classes from sqlalchemy.types mapped
1027 to subclasses that are specific to the dialect class. This
1028 dictionary is class-level only and is not accessed from the
1029 dialect instance itself.
1030 """
1031
1032 supports_sequences: bool
1033 """Indicates if the dialect supports CREATE SEQUENCE or similar."""
1034
1035 sequences_optional: bool
1036 """If True, indicates if the :paramref:`_schema.Sequence.optional`
1037 parameter on the :class:`_schema.Sequence` construct
1038 should signal to not generate a CREATE SEQUENCE. Applies only to
1039 dialects that support sequences. Currently used only to allow PostgreSQL
1040 SERIAL to be used on a column that specifies Sequence() for usage on
1041 other backends.
1042 """
1043
1044 default_sequence_base: int
1045 """the default value that will be rendered as the "START WITH" portion of
1046 a CREATE SEQUENCE DDL statement.
1047
1048 """
1049
1050 supports_native_enum: bool
1051 """Indicates if the dialect supports a native ENUM construct.
1052 This will prevent :class:`_types.Enum` from generating a CHECK
1053 constraint when that type is used in "native" mode.
1054 """
1055
1056 supports_native_boolean: bool
1057 """Indicates if the dialect supports a native boolean construct.
1058 This will prevent :class:`_types.Boolean` from generating a CHECK
1059 constraint when that type is used.
1060 """
1061
1062 supports_native_decimal: bool
1063 """indicates if Decimal objects are handled and returned for precision
1064 numeric types, or if floats are returned"""
1065
1066 supports_native_uuid: bool
1067 """indicates if Python UUID() objects are handled natively by the
1068 driver for SQL UUID datatypes.
1069
1070 .. versionadded:: 2.0
1071
1072 """
1073
1074 returns_native_bytes: bool
1075 """indicates if Python bytes() objects are returned natively by the
1076 driver for SQL "binary" datatypes.
1077
1078 .. versionadded:: 2.0.11
1079
1080 """
1081
1082 construct_arguments: Optional[
1083 List[Tuple[Type[Union[SchemaItem, ClauseElement]], Mapping[str, Any]]]
1084 ] = None
1085 """Optional set of argument specifiers for various SQLAlchemy
1086 constructs, typically schema items.
1087
1088 To implement, establish as a series of tuples, as in::
1089
1090 construct_arguments = [
1091 (schema.Index, {"using": False, "where": None, "ops": None}),
1092 ]
1093
1094 If the above construct is established on the PostgreSQL dialect,
1095 the :class:`.Index` construct will now accept the keyword arguments
1096 ``postgresql_using``, ``postgresql_where``, nad ``postgresql_ops``.
1097 Any other argument specified to the constructor of :class:`.Index`
1098 which is prefixed with ``postgresql_`` will raise :class:`.ArgumentError`.
1099
1100 A dialect which does not include a ``construct_arguments`` member will
1101 not participate in the argument validation system. For such a dialect,
1102 any argument name is accepted by all participating constructs, within
1103 the namespace of arguments prefixed with that dialect name. The rationale
1104 here is so that third-party dialects that haven't yet implemented this
1105 feature continue to function in the old way.
1106
1107 .. seealso::
1108
1109 :class:`.DialectKWArgs` - implementing base class which consumes
1110 :attr:`.DefaultDialect.construct_arguments`
1111
1112
1113 """
1114
1115 reflection_options: Sequence[str] = ()
1116 """Sequence of string names indicating keyword arguments that can be
1117 established on a :class:`.Table` object which will be passed as
1118 "reflection options" when using :paramref:`.Table.autoload_with`.
1119
1120 Current example is "oracle_resolve_synonyms" in the Oracle Database
1121 dialects.
1122
1123 """
1124
1125 dbapi_exception_translation_map: Mapping[str, str] = util.EMPTY_DICT
1126 """A dictionary of names that will contain as values the names of
1127 pep-249 exceptions ("IntegrityError", "OperationalError", etc)
1128 keyed to alternate class names, to support the case where a
1129 DBAPI has exception classes that aren't named as they are
1130 referred to (e.g. IntegrityError = MyException). In the vast
1131 majority of cases this dictionary is empty.
1132 """
1133
1134 supports_comments: bool
1135 """Indicates the dialect supports comment DDL on tables and columns."""
1136
1137 inline_comments: bool
1138 """Indicates the dialect supports comment DDL that's inline with the
1139 definition of a Table or Column. If False, this implies that ALTER must
1140 be used to set table and column comments."""
1141
1142 supports_constraint_comments: bool
1143 """Indicates if the dialect supports comment DDL on constraints.
1144
1145 .. versionadded:: 2.0
1146 """
1147
1148 _has_events = False
1149
1150 supports_statement_cache: bool = True
1151 """indicates if this dialect supports caching.
1152
1153 All dialects that are compatible with statement caching should set this
1154 flag to True directly on each dialect class and subclass that supports
1155 it. SQLAlchemy tests that this flag is locally present on each dialect
1156 subclass before it will use statement caching. This is to provide
1157 safety for legacy or new dialects that are not yet fully tested to be
1158 compliant with SQL statement caching.
1159
1160 .. versionadded:: 1.4.5
1161
1162 .. seealso::
1163
1164 :ref:`engine_thirdparty_caching`
1165
1166 """
1167
1168 _supports_statement_cache: bool
1169 """internal evaluation for supports_statement_cache"""
1170
1171 bind_typing = BindTyping.NONE
1172 """define a means of passing typing information to the database and/or
1173 driver for bound parameters.
1174
1175 See :class:`.BindTyping` for values.
1176
1177 .. versionadded:: 2.0
1178
1179 """
1180
1181 is_async: bool
1182 """Whether or not this dialect is intended for asyncio use."""
1183
1184 has_terminate: bool
1185 """Whether or not this dialect has a separate "terminate" implementation
1186 that does not block or require awaiting."""
1187
1188 engine_config_types: Mapping[str, Any]
1189 """a mapping of string keys that can be in an engine config linked to
1190 type conversion functions.
1191
1192 """
1193
1194 label_length: Optional[int]
1195 """optional user-defined max length for SQL labels"""
1196
1197 include_set_input_sizes: Optional[Set[Any]]
1198 """set of DBAPI type objects that should be included in
1199 automatic cursor.setinputsizes() calls.
1200
1201 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES
1202
1203 """
1204
1205 exclude_set_input_sizes: Optional[Set[Any]]
1206 """set of DBAPI type objects that should be excluded in
1207 automatic cursor.setinputsizes() calls.
1208
1209 This is only used if bind_typing is BindTyping.SET_INPUT_SIZES
1210
1211 """
1212
1213 supports_simple_order_by_label: bool
1214 """target database supports ORDER BY <labelname>, where <labelname>
1215 refers to a label in the columns clause of the SELECT"""
1216
1217 div_is_floordiv: bool
1218 """target database treats the / division operator as "floor division" """
1219
1220 tuple_in_values: bool
1221 """target database supports tuple IN, i.e. (x, y) IN ((q, p), (r, z))"""
1222
1223 _bind_typing_render_casts: bool
1224
1225 _type_memos: MutableMapping[TypeEngine[Any], _TypeMemoDict]
1226
1227 def _builtin_onconnect(self) -> Optional[_ListenerFnType]:
1228 raise NotImplementedError()
1229
1230 def create_connect_args(self, url: URL) -> ConnectArgsType:
1231 """Build DB-API compatible connection arguments.
1232
1233 Given a :class:`.URL` object, returns a tuple
1234 consisting of a ``(*args, **kwargs)`` suitable to send directly
1235 to the dbapi's connect function. The arguments are sent to the
1236 :meth:`.Dialect.connect` method which then runs the DBAPI-level
1237 ``connect()`` function.
1238
1239 The method typically makes use of the
1240 :meth:`.URL.translate_connect_args`
1241 method in order to generate a dictionary of options.
1242
1243 The default implementation is::
1244
1245 def create_connect_args(self, url):
1246 opts = url.translate_connect_args()
1247 opts.update(url.query)
1248 return ([], opts)
1249
1250 :param url: a :class:`.URL` object
1251
1252 :return: a tuple of ``(*args, **kwargs)`` which will be passed to the
1253 :meth:`.Dialect.connect` method.
1254
1255 .. seealso::
1256
1257 :meth:`.URL.translate_connect_args`
1258
1259 """
1260
1261 raise NotImplementedError()
1262
1263 @classmethod
1264 def import_dbapi(cls) -> DBAPIModule:
1265 """Import the DBAPI module that is used by this dialect.
1266
1267 The Python module object returned here will be assigned as an
1268 instance variable to a constructed dialect under the name
1269 ``.dbapi``.
1270
1271 .. versionchanged:: 2.0 The :meth:`.Dialect.import_dbapi` class
1272 method is renamed from the previous method ``.Dialect.dbapi()``,
1273 which would be replaced at dialect instantiation time by the
1274 DBAPI module itself, thus using the same name in two different ways.
1275 If a ``.Dialect.dbapi()`` classmethod is present on a third-party
1276 dialect, it will be used and a deprecation warning will be emitted.
1277
1278 """
1279 raise NotImplementedError()
1280
1281 def type_descriptor(self, typeobj: TypeEngine[_T]) -> TypeEngine[_T]:
1282 """Transform a generic type to a dialect-specific type.
1283
1284 Dialect classes will usually use the
1285 :func:`_types.adapt_type` function in the types module to
1286 accomplish this.
1287
1288 The returned result is cached *per dialect class* so can
1289 contain no dialect-instance state.
1290
1291 """
1292
1293 raise NotImplementedError()
1294
1295 def initialize(self, connection: Connection) -> None:
1296 """Called during strategized creation of the dialect with a
1297 connection.
1298
1299 Allows dialects to configure options based on server version info or
1300 other properties.
1301
1302 The connection passed here is a SQLAlchemy Connection object,
1303 with full capabilities.
1304
1305 The initialize() method of the base dialect should be called via
1306 super().
1307
1308 .. note:: as of SQLAlchemy 1.4, this method is called **before**
1309 any :meth:`_engine.Dialect.on_connect` hooks are called.
1310
1311 """
1312
1313 if TYPE_CHECKING:
1314
1315 def _overrides_default(self, method_name: str) -> bool: ...
1316
1317 def get_columns(
1318 self,
1319 connection: Connection,
1320 table_name: str,
1321 schema: Optional[str] = None,
1322 **kw: Any,
1323 ) -> List[ReflectedColumn]:
1324 """Return information about columns in ``table_name``.
1325
1326 Given a :class:`_engine.Connection`, a string
1327 ``table_name``, and an optional string ``schema``, return column
1328 information as a list of dictionaries
1329 corresponding to the :class:`.ReflectedColumn` dictionary.
1330
1331 This is an internal dialect method. Applications should use
1332 :meth:`.Inspector.get_columns`.
1333
1334 """
1335
1336 raise NotImplementedError()
1337
1338 def get_multi_columns(
1339 self,
1340 connection: Connection,
1341 *,
1342 schema: Optional[str] = None,
1343 filter_names: Optional[Collection[str]] = None,
1344 **kw: Any,
1345 ) -> Iterable[Tuple[TableKey, List[ReflectedColumn]]]:
1346 """Return information about columns in all tables in the
1347 given ``schema``.
1348
1349 This is an internal dialect method. Applications should use
1350 :meth:`.Inspector.get_multi_columns`.
1351
1352 .. note:: The :class:`_engine.DefaultDialect` provides a default
1353 implementation that will call the single table method for
1354 each object returned by :meth:`Dialect.get_table_names`,
1355 :meth:`Dialect.get_view_names` or
1356 :meth:`Dialect.get_materialized_view_names` depending on the
1357 provided ``kind``. Dialects that want to support a faster
1358 implementation should implement this method.
1359
1360 .. versionadded:: 2.0
1361
1362 """
1363
1364 raise NotImplementedError()
1365
1366 def get_pk_constraint(
1367 self,
1368 connection: Connection,
1369 table_name: str,
1370 schema: Optional[str] = None,
1371 **kw: Any,
1372 ) -> ReflectedPrimaryKeyConstraint:
1373 """Return information about the primary key constraint on
1374 table_name`.
1375
1376 Given a :class:`_engine.Connection`, a string
1377 ``table_name``, and an optional string ``schema``, return primary
1378 key information as a dictionary corresponding to the
1379 :class:`.ReflectedPrimaryKeyConstraint` dictionary.
1380
1381 This is an internal dialect method. Applications should use
1382 :meth:`.Inspector.get_pk_constraint`.
1383
1384 """
1385 raise NotImplementedError()
1386
1387 def get_multi_pk_constraint(
1388 self,
1389 connection: Connection,
1390 *,
1391 schema: Optional[str] = None,
1392 filter_names: Optional[Collection[str]] = None,
1393 **kw: Any,
1394 ) -> Iterable[Tuple[TableKey, ReflectedPrimaryKeyConstraint]]:
1395 """Return information about primary key constraints in
1396 all tables in the given ``schema``.
1397
1398 This is an internal dialect method. Applications should use
1399 :meth:`.Inspector.get_multi_pk_constraint`.
1400
1401 .. note:: The :class:`_engine.DefaultDialect` provides a default
1402 implementation that will call the single table method for
1403 each object returned by :meth:`Dialect.get_table_names`,
1404 :meth:`Dialect.get_view_names` or
1405 :meth:`Dialect.get_materialized_view_names` depending on the
1406 provided ``kind``. Dialects that want to support a faster
1407 implementation should implement this method.
1408
1409 .. versionadded:: 2.0
1410
1411 """
1412 raise NotImplementedError()
1413
1414 def get_foreign_keys(
1415 self,
1416 connection: Connection,
1417 table_name: str,
1418 schema: Optional[str] = None,
1419 **kw: Any,
1420 ) -> List[ReflectedForeignKeyConstraint]:
1421 """Return information about foreign_keys in ``table_name``.
1422
1423 Given a :class:`_engine.Connection`, a string
1424 ``table_name``, and an optional string ``schema``, return foreign
1425 key information as a list of dicts corresponding to the
1426 :class:`.ReflectedForeignKeyConstraint` dictionary.
1427
1428 This is an internal dialect method. Applications should use
1429 :meth:`_engine.Inspector.get_foreign_keys`.
1430 """
1431
1432 raise NotImplementedError()
1433
1434 def get_multi_foreign_keys(
1435 self,
1436 connection: Connection,
1437 *,
1438 schema: Optional[str] = None,
1439 filter_names: Optional[Collection[str]] = None,
1440 **kw: Any,
1441 ) -> Iterable[Tuple[TableKey, List[ReflectedForeignKeyConstraint]]]:
1442 """Return information about foreign_keys in all tables
1443 in the given ``schema``.
1444
1445 This is an internal dialect method. Applications should use
1446 :meth:`_engine.Inspector.get_multi_foreign_keys`.
1447
1448 .. note:: The :class:`_engine.DefaultDialect` provides a default
1449 implementation that will call the single table method for
1450 each object returned by :meth:`Dialect.get_table_names`,
1451 :meth:`Dialect.get_view_names` or
1452 :meth:`Dialect.get_materialized_view_names` depending on the
1453 provided ``kind``. Dialects that want to support a faster
1454 implementation should implement this method.
1455
1456 .. versionadded:: 2.0
1457
1458 """
1459
1460 raise NotImplementedError()
1461
1462 def get_table_names(
1463 self, connection: Connection, schema: Optional[str] = None, **kw: Any
1464 ) -> List[str]:
1465 """Return a list of table names for ``schema``.
1466
1467 This is an internal dialect method. Applications should use
1468 :meth:`_engine.Inspector.get_table_names`.
1469
1470 """
1471
1472 raise NotImplementedError()
1473
1474 def get_temp_table_names(
1475 self, connection: Connection, schema: Optional[str] = None, **kw: Any
1476 ) -> List[str]:
1477 """Return a list of temporary table names on the given connection,
1478 if supported by the underlying backend.
1479
1480 This is an internal dialect method. Applications should use
1481 :meth:`_engine.Inspector.get_temp_table_names`.
1482
1483 """
1484
1485 raise NotImplementedError()
1486
1487 def get_view_names(
1488 self, connection: Connection, schema: Optional[str] = None, **kw: Any
1489 ) -> List[str]:
1490 """Return a list of all non-materialized view names available in the
1491 database.
1492
1493 This is an internal dialect method. Applications should use
1494 :meth:`_engine.Inspector.get_view_names`.
1495
1496 :param schema: schema name to query, if not the default schema.
1497
1498 """
1499
1500 raise NotImplementedError()
1501
1502 def get_materialized_view_names(
1503 self, connection: Connection, schema: Optional[str] = None, **kw: Any
1504 ) -> List[str]:
1505 """Return a list of all materialized view names available in the
1506 database.
1507
1508 This is an internal dialect method. Applications should use
1509 :meth:`_engine.Inspector.get_materialized_view_names`.
1510
1511 :param schema: schema name to query, if not the default schema.
1512
1513 .. versionadded:: 2.0
1514
1515 """
1516
1517 raise NotImplementedError()
1518
1519 def get_sequence_names(
1520 self, connection: Connection, schema: Optional[str] = None, **kw: Any
1521 ) -> List[str]:
1522 """Return a list of all sequence names available in the database.
1523
1524 This is an internal dialect method. Applications should use
1525 :meth:`_engine.Inspector.get_sequence_names`.
1526
1527 :param schema: schema name to query, if not the default schema.
1528
1529 .. versionadded:: 1.4
1530 """
1531
1532 raise NotImplementedError()
1533
1534 def get_temp_view_names(
1535 self, connection: Connection, schema: Optional[str] = None, **kw: Any
1536 ) -> List[str]:
1537 """Return a list of temporary view names on the given connection,
1538 if supported by the underlying backend.
1539
1540 This is an internal dialect method. Applications should use
1541 :meth:`_engine.Inspector.get_temp_view_names`.
1542
1543 """
1544
1545 raise NotImplementedError()
1546
1547 def get_schema_names(self, connection: Connection, **kw: Any) -> List[str]:
1548 """Return a list of all schema names available in the database.
1549
1550 This is an internal dialect method. Applications should use
1551 :meth:`_engine.Inspector.get_schema_names`.
1552 """
1553 raise NotImplementedError()
1554
1555 def get_view_definition(
1556 self,
1557 connection: Connection,
1558 view_name: str,
1559 schema: Optional[str] = None,
1560 **kw: Any,
1561 ) -> str:
1562 """Return plain or materialized view definition.
1563
1564 This is an internal dialect method. Applications should use
1565 :meth:`_engine.Inspector.get_view_definition`.
1566
1567 Given a :class:`_engine.Connection`, a string
1568 ``view_name``, and an optional string ``schema``, return the view
1569 definition.
1570 """
1571
1572 raise NotImplementedError()
1573
1574 def get_indexes(
1575 self,
1576 connection: Connection,
1577 table_name: str,
1578 schema: Optional[str] = None,
1579 **kw: Any,
1580 ) -> List[ReflectedIndex]:
1581 """Return information about indexes in ``table_name``.
1582
1583 Given a :class:`_engine.Connection`, a string
1584 ``table_name`` and an optional string ``schema``, return index
1585 information as a list of dictionaries corresponding to the
1586 :class:`.ReflectedIndex` dictionary.
1587
1588 This is an internal dialect method. Applications should use
1589 :meth:`.Inspector.get_indexes`.
1590 """
1591
1592 raise NotImplementedError()
1593
1594 def get_multi_indexes(
1595 self,
1596 connection: Connection,
1597 *,
1598 schema: Optional[str] = None,
1599 filter_names: Optional[Collection[str]] = None,
1600 **kw: Any,
1601 ) -> Iterable[Tuple[TableKey, List[ReflectedIndex]]]:
1602 """Return information about indexes in in all tables
1603 in the given ``schema``.
1604
1605 This is an internal dialect method. Applications should use
1606 :meth:`.Inspector.get_multi_indexes`.
1607
1608 .. note:: The :class:`_engine.DefaultDialect` provides a default
1609 implementation that will call the single table method for
1610 each object returned by :meth:`Dialect.get_table_names`,
1611 :meth:`Dialect.get_view_names` or
1612 :meth:`Dialect.get_materialized_view_names` depending on the
1613 provided ``kind``. Dialects that want to support a faster
1614 implementation should implement this method.
1615
1616 .. versionadded:: 2.0
1617
1618 """
1619
1620 raise NotImplementedError()
1621
1622 def get_unique_constraints(
1623 self,
1624 connection: Connection,
1625 table_name: str,
1626 schema: Optional[str] = None,
1627 **kw: Any,
1628 ) -> List[ReflectedUniqueConstraint]:
1629 r"""Return information about unique constraints in ``table_name``.
1630
1631 Given a string ``table_name`` and an optional string ``schema``, return
1632 unique constraint information as a list of dicts corresponding
1633 to the :class:`.ReflectedUniqueConstraint` dictionary.
1634
1635 This is an internal dialect method. Applications should use
1636 :meth:`.Inspector.get_unique_constraints`.
1637 """
1638
1639 raise NotImplementedError()
1640
1641 def get_multi_unique_constraints(
1642 self,
1643 connection: Connection,
1644 *,
1645 schema: Optional[str] = None,
1646 filter_names: Optional[Collection[str]] = None,
1647 **kw: Any,
1648 ) -> Iterable[Tuple[TableKey, List[ReflectedUniqueConstraint]]]:
1649 """Return information about unique constraints in all tables
1650 in the given ``schema``.
1651
1652 This is an internal dialect method. Applications should use
1653 :meth:`.Inspector.get_multi_unique_constraints`.
1654
1655 .. note:: The :class:`_engine.DefaultDialect` provides a default
1656 implementation that will call the single table method for
1657 each object returned by :meth:`Dialect.get_table_names`,
1658 :meth:`Dialect.get_view_names` or
1659 :meth:`Dialect.get_materialized_view_names` depending on the
1660 provided ``kind``. Dialects that want to support a faster
1661 implementation should implement this method.
1662
1663 .. versionadded:: 2.0
1664
1665 """
1666
1667 raise NotImplementedError()
1668
1669 def get_check_constraints(
1670 self,
1671 connection: Connection,
1672 table_name: str,
1673 schema: Optional[str] = None,
1674 **kw: Any,
1675 ) -> List[ReflectedCheckConstraint]:
1676 r"""Return information about check constraints in ``table_name``.
1677
1678 Given a string ``table_name`` and an optional string ``schema``, return
1679 check constraint information as a list of dicts corresponding
1680 to the :class:`.ReflectedCheckConstraint` dictionary.
1681
1682 This is an internal dialect method. Applications should use
1683 :meth:`.Inspector.get_check_constraints`.
1684
1685 """
1686
1687 raise NotImplementedError()
1688
1689 def get_multi_check_constraints(
1690 self,
1691 connection: Connection,
1692 *,
1693 schema: Optional[str] = None,
1694 filter_names: Optional[Collection[str]] = None,
1695 **kw: Any,
1696 ) -> Iterable[Tuple[TableKey, List[ReflectedCheckConstraint]]]:
1697 """Return information about check constraints in all tables
1698 in the given ``schema``.
1699
1700 This is an internal dialect method. Applications should use
1701 :meth:`.Inspector.get_multi_check_constraints`.
1702
1703 .. note:: The :class:`_engine.DefaultDialect` provides a default
1704 implementation that will call the single table method for
1705 each object returned by :meth:`Dialect.get_table_names`,
1706 :meth:`Dialect.get_view_names` or
1707 :meth:`Dialect.get_materialized_view_names` depending on the
1708 provided ``kind``. Dialects that want to support a faster
1709 implementation should implement this method.
1710
1711 .. versionadded:: 2.0
1712
1713 """
1714
1715 raise NotImplementedError()
1716
1717 def get_table_options(
1718 self,
1719 connection: Connection,
1720 table_name: str,
1721 schema: Optional[str] = None,
1722 **kw: Any,
1723 ) -> Dict[str, Any]:
1724 """Return a dictionary of options specified when ``table_name``
1725 was created.
1726
1727 This is an internal dialect method. Applications should use
1728 :meth:`_engine.Inspector.get_table_options`.
1729 """
1730 raise NotImplementedError()
1731
1732 def get_multi_table_options(
1733 self,
1734 connection: Connection,
1735 *,
1736 schema: Optional[str] = None,
1737 filter_names: Optional[Collection[str]] = None,
1738 **kw: Any,
1739 ) -> Iterable[Tuple[TableKey, Dict[str, Any]]]:
1740 """Return a dictionary of options specified when the tables in the
1741 given schema were created.
1742
1743 This is an internal dialect method. Applications should use
1744 :meth:`_engine.Inspector.get_multi_table_options`.
1745
1746 .. note:: The :class:`_engine.DefaultDialect` provides a default
1747 implementation that will call the single table method for
1748 each object returned by :meth:`Dialect.get_table_names`,
1749 :meth:`Dialect.get_view_names` or
1750 :meth:`Dialect.get_materialized_view_names` depending on the
1751 provided ``kind``. Dialects that want to support a faster
1752 implementation should implement this method.
1753
1754 .. versionadded:: 2.0
1755
1756 """
1757 raise NotImplementedError()
1758
1759 def get_table_comment(
1760 self,
1761 connection: Connection,
1762 table_name: str,
1763 schema: Optional[str] = None,
1764 **kw: Any,
1765 ) -> ReflectedTableComment:
1766 r"""Return the "comment" for the table identified by ``table_name``.
1767
1768 Given a string ``table_name`` and an optional string ``schema``, return
1769 table comment information as a dictionary corresponding to the
1770 :class:`.ReflectedTableComment` dictionary.
1771
1772 This is an internal dialect method. Applications should use
1773 :meth:`.Inspector.get_table_comment`.
1774
1775 :raise: ``NotImplementedError`` for dialects that don't support
1776 comments.
1777
1778 """
1779
1780 raise NotImplementedError()
1781
1782 def get_multi_table_comment(
1783 self,
1784 connection: Connection,
1785 *,
1786 schema: Optional[str] = None,
1787 filter_names: Optional[Collection[str]] = None,
1788 **kw: Any,
1789 ) -> Iterable[Tuple[TableKey, ReflectedTableComment]]:
1790 """Return information about the table comment in all tables
1791 in the given ``schema``.
1792
1793 This is an internal dialect method. Applications should use
1794 :meth:`_engine.Inspector.get_multi_table_comment`.
1795
1796 .. note:: The :class:`_engine.DefaultDialect` provides a default
1797 implementation that will call the single table method for
1798 each object returned by :meth:`Dialect.get_table_names`,
1799 :meth:`Dialect.get_view_names` or
1800 :meth:`Dialect.get_materialized_view_names` depending on the
1801 provided ``kind``. Dialects that want to support a faster
1802 implementation should implement this method.
1803
1804 .. versionadded:: 2.0
1805
1806 """
1807
1808 raise NotImplementedError()
1809
1810 def normalize_name(self, name: str) -> str:
1811 """convert the given name to lowercase if it is detected as
1812 case insensitive.
1813
1814 This method is only used if the dialect defines
1815 requires_name_normalize=True.
1816
1817 """
1818 raise NotImplementedError()
1819
1820 def denormalize_name(self, name: str) -> str:
1821 """convert the given name to a case insensitive identifier
1822 for the backend if it is an all-lowercase name.
1823
1824 This method is only used if the dialect defines
1825 requires_name_normalize=True.
1826
1827 """
1828 raise NotImplementedError()
1829
1830 def has_table(
1831 self,
1832 connection: Connection,
1833 table_name: str,
1834 schema: Optional[str] = None,
1835 **kw: Any,
1836 ) -> bool:
1837 """For internal dialect use, check the existence of a particular table
1838 or view in the database.
1839
1840 Given a :class:`_engine.Connection` object, a string table_name and
1841 optional schema name, return True if the given table exists in the
1842 database, False otherwise.
1843
1844 This method serves as the underlying implementation of the
1845 public facing :meth:`.Inspector.has_table` method, and is also used
1846 internally to implement the "checkfirst" behavior for methods like
1847 :meth:`_schema.Table.create` and :meth:`_schema.MetaData.create_all`.
1848
1849 .. note:: This method is used internally by SQLAlchemy, and is
1850 published so that third-party dialects may provide an
1851 implementation. It is **not** the public API for checking for table
1852 presence. Please use the :meth:`.Inspector.has_table` method.
1853
1854 .. versionchanged:: 2.0:: :meth:`_engine.Dialect.has_table` now
1855 formally supports checking for additional table-like objects:
1856
1857 * any type of views (plain or materialized)
1858 * temporary tables of any kind
1859
1860 Previously, these two checks were not formally specified and
1861 different dialects would vary in their behavior. The dialect
1862 testing suite now includes tests for all of these object types,
1863 and dialects to the degree that the backing database supports views
1864 or temporary tables should seek to support locating these objects
1865 for full compliance.
1866
1867 """
1868
1869 raise NotImplementedError()
1870
1871 def has_index(
1872 self,
1873 connection: Connection,
1874 table_name: str,
1875 index_name: str,
1876 schema: Optional[str] = None,
1877 **kw: Any,
1878 ) -> bool:
1879 """Check the existence of a particular index name in the database.
1880
1881 Given a :class:`_engine.Connection` object, a string
1882 ``table_name`` and string index name, return ``True`` if an index of
1883 the given name on the given table exists, ``False`` otherwise.
1884
1885 The :class:`.DefaultDialect` implements this in terms of the
1886 :meth:`.Dialect.has_table` and :meth:`.Dialect.get_indexes` methods,
1887 however dialects can implement a more performant version.
1888
1889 This is an internal dialect method. Applications should use
1890 :meth:`_engine.Inspector.has_index`.
1891
1892 .. versionadded:: 1.4
1893
1894 """
1895
1896 raise NotImplementedError()
1897
1898 def has_sequence(
1899 self,
1900 connection: Connection,
1901 sequence_name: str,
1902 schema: Optional[str] = None,
1903 **kw: Any,
1904 ) -> bool:
1905 """Check the existence of a particular sequence in the database.
1906
1907 Given a :class:`_engine.Connection` object and a string
1908 `sequence_name`, return ``True`` if the given sequence exists in
1909 the database, ``False`` otherwise.
1910
1911 This is an internal dialect method. Applications should use
1912 :meth:`_engine.Inspector.has_sequence`.
1913 """
1914
1915 raise NotImplementedError()
1916
1917 def has_schema(
1918 self, connection: Connection, schema_name: str, **kw: Any
1919 ) -> bool:
1920 """Check the existence of a particular schema name in the database.
1921
1922 Given a :class:`_engine.Connection` object, a string
1923 ``schema_name``, return ``True`` if a schema of the
1924 given exists, ``False`` otherwise.
1925
1926 The :class:`.DefaultDialect` implements this by checking
1927 the presence of ``schema_name`` among the schemas returned by
1928 :meth:`.Dialect.get_schema_names`,
1929 however dialects can implement a more performant version.
1930
1931 This is an internal dialect method. Applications should use
1932 :meth:`_engine.Inspector.has_schema`.
1933
1934 .. versionadded:: 2.0
1935
1936 """
1937
1938 raise NotImplementedError()
1939
1940 def _get_server_version_info(self, connection: Connection) -> Any:
1941 """Retrieve the server version info from the given connection.
1942
1943 This is used by the default implementation to populate the
1944 "server_version_info" attribute and is called exactly
1945 once upon first connect.
1946
1947 """
1948
1949 raise NotImplementedError()
1950
1951 def _get_default_schema_name(self, connection: Connection) -> str:
1952 """Return the string name of the currently selected schema from
1953 the given connection.
1954
1955 This is used by the default implementation to populate the
1956 "default_schema_name" attribute and is called exactly
1957 once upon first connect.
1958
1959 """
1960
1961 raise NotImplementedError()
1962
1963 def do_begin(self, dbapi_connection: PoolProxiedConnection) -> None:
1964 """Provide an implementation of ``connection.begin()``, given a
1965 DB-API connection.
1966
1967 The DBAPI has no dedicated "begin" method and it is expected
1968 that transactions are implicit. This hook is provided for those
1969 DBAPIs that might need additional help in this area.
1970
1971 :param dbapi_connection: a DBAPI connection, typically
1972 proxied within a :class:`.ConnectionFairy`.
1973
1974 """
1975
1976 raise NotImplementedError()
1977
1978 def do_rollback(self, dbapi_connection: PoolProxiedConnection) -> None:
1979 """Provide an implementation of ``connection.rollback()``, given
1980 a DB-API connection.
1981
1982 :param dbapi_connection: a DBAPI connection, typically
1983 proxied within a :class:`.ConnectionFairy`.
1984
1985 """
1986
1987 raise NotImplementedError()
1988
1989 def do_commit(self, dbapi_connection: PoolProxiedConnection) -> None:
1990 """Provide an implementation of ``connection.commit()``, given a
1991 DB-API connection.
1992
1993 :param dbapi_connection: a DBAPI connection, typically
1994 proxied within a :class:`.ConnectionFairy`.
1995
1996 """
1997
1998 raise NotImplementedError()
1999
2000 def do_terminate(self, dbapi_connection: DBAPIConnection) -> None:
2001 """Provide an implementation of ``connection.close()`` that tries as
2002 much as possible to not block, given a DBAPI
2003 connection.
2004
2005 In the vast majority of cases this just calls .close(), however
2006 for some asyncio dialects may call upon different API features.
2007
2008 This hook is called by the :class:`_pool.Pool`
2009 when a connection is being recycled or has been invalidated.
2010
2011 .. versionadded:: 1.4.41
2012
2013 """
2014
2015 raise NotImplementedError()
2016
2017 def do_close(self, dbapi_connection: DBAPIConnection) -> None:
2018 """Provide an implementation of ``connection.close()``, given a DBAPI
2019 connection.
2020
2021 This hook is called by the :class:`_pool.Pool`
2022 when a connection has been
2023 detached from the pool, or is being returned beyond the normal
2024 capacity of the pool.
2025
2026 """
2027
2028 raise NotImplementedError()
2029
2030 def _do_ping_w_event(self, dbapi_connection: DBAPIConnection) -> bool:
2031 raise NotImplementedError()
2032
2033 def do_ping(self, dbapi_connection: DBAPIConnection) -> bool:
2034 """ping the DBAPI connection and return True if the connection is
2035 usable."""
2036 raise NotImplementedError()
2037
2038 def do_set_input_sizes(
2039 self,
2040 cursor: DBAPICursor,
2041 list_of_tuples: _GenericSetInputSizesType,
2042 context: ExecutionContext,
2043 ) -> Any:
2044 """invoke the cursor.setinputsizes() method with appropriate arguments
2045
2046 This hook is called if the :attr:`.Dialect.bind_typing` attribute is
2047 set to the
2048 :attr:`.BindTyping.SETINPUTSIZES` value.
2049 Parameter data is passed in a list of tuples (paramname, dbtype,
2050 sqltype), where ``paramname`` is the key of the parameter in the
2051 statement, ``dbtype`` is the DBAPI datatype and ``sqltype`` is the
2052 SQLAlchemy type. The order of tuples is in the correct parameter order.
2053
2054 .. versionadded:: 1.4
2055
2056 .. versionchanged:: 2.0 - setinputsizes mode is now enabled by
2057 setting :attr:`.Dialect.bind_typing` to
2058 :attr:`.BindTyping.SETINPUTSIZES`. Dialects which accept
2059 a ``use_setinputsizes`` parameter should set this value
2060 appropriately.
2061
2062
2063 """
2064 raise NotImplementedError()
2065
2066 def create_xid(self) -> Any:
2067 """Create a two-phase transaction ID.
2068
2069 This id will be passed to do_begin_twophase(),
2070 do_rollback_twophase(), do_commit_twophase(). Its format is
2071 unspecified.
2072 """
2073
2074 raise NotImplementedError()
2075
2076 def do_savepoint(self, connection: Connection, name: str) -> None:
2077 """Create a savepoint with the given name.
2078
2079 :param connection: a :class:`_engine.Connection`.
2080 :param name: savepoint name.
2081
2082 """
2083
2084 raise NotImplementedError()
2085
2086 def do_rollback_to_savepoint(
2087 self, connection: Connection, name: str
2088 ) -> None:
2089 """Rollback a connection to the named savepoint.
2090
2091 :param connection: a :class:`_engine.Connection`.
2092 :param name: savepoint name.
2093
2094 """
2095
2096 raise NotImplementedError()
2097
2098 def do_release_savepoint(self, connection: Connection, name: str) -> None:
2099 """Release the named savepoint on a connection.
2100
2101 :param connection: a :class:`_engine.Connection`.
2102 :param name: savepoint name.
2103 """
2104
2105 raise NotImplementedError()
2106
2107 def do_begin_twophase(self, connection: Connection, xid: Any) -> None:
2108 """Begin a two phase transaction on the given connection.
2109
2110 :param connection: a :class:`_engine.Connection`.
2111 :param xid: xid
2112
2113 """
2114
2115 raise NotImplementedError()
2116
2117 def do_prepare_twophase(self, connection: Connection, xid: Any) -> None:
2118 """Prepare a two phase transaction on the given connection.
2119
2120 :param connection: a :class:`_engine.Connection`.
2121 :param xid: xid
2122
2123 """
2124
2125 raise NotImplementedError()
2126
2127 def do_rollback_twophase(
2128 self,
2129 connection: Connection,
2130 xid: Any,
2131 is_prepared: bool = True,
2132 recover: bool = False,
2133 ) -> None:
2134 """Rollback a two phase transaction on the given connection.
2135
2136 :param connection: a :class:`_engine.Connection`.
2137 :param xid: xid
2138 :param is_prepared: whether or not
2139 :meth:`.TwoPhaseTransaction.prepare` was called.
2140 :param recover: if the recover flag was passed.
2141
2142 """
2143
2144 raise NotImplementedError()
2145
2146 def do_commit_twophase(
2147 self,
2148 connection: Connection,
2149 xid: Any,
2150 is_prepared: bool = True,
2151 recover: bool = False,
2152 ) -> None:
2153 """Commit a two phase transaction on the given connection.
2154
2155
2156 :param connection: a :class:`_engine.Connection`.
2157 :param xid: xid
2158 :param is_prepared: whether or not
2159 :meth:`.TwoPhaseTransaction.prepare` was called.
2160 :param recover: if the recover flag was passed.
2161
2162 """
2163
2164 raise NotImplementedError()
2165
2166 def do_recover_twophase(self, connection: Connection) -> List[Any]:
2167 """Recover list of uncommitted prepared two phase transaction
2168 identifiers on the given connection.
2169
2170 :param connection: a :class:`_engine.Connection`.
2171
2172 """
2173
2174 raise NotImplementedError()
2175
2176 def _deliver_insertmanyvalues_batches(
2177 self,
2178 connection: Connection,
2179 cursor: DBAPICursor,
2180 statement: str,
2181 parameters: _DBAPIMultiExecuteParams,
2182 generic_setinputsizes: Optional[_GenericSetInputSizesType],
2183 context: ExecutionContext,
2184 ) -> Iterator[_InsertManyValuesBatch]:
2185 """convert executemany parameters for an INSERT into an iterator
2186 of statement/single execute values, used by the insertmanyvalues
2187 feature.
2188
2189 """
2190 raise NotImplementedError()
2191
2192 def do_executemany(
2193 self,
2194 cursor: DBAPICursor,
2195 statement: str,
2196 parameters: _DBAPIMultiExecuteParams,
2197 context: Optional[ExecutionContext] = None,
2198 ) -> None:
2199 """Provide an implementation of ``cursor.executemany(statement,
2200 parameters)``."""
2201
2202 raise NotImplementedError()
2203
2204 def do_execute(
2205 self,
2206 cursor: DBAPICursor,
2207 statement: str,
2208 parameters: Optional[_DBAPISingleExecuteParams],
2209 context: Optional[ExecutionContext] = None,
2210 ) -> None:
2211 """Provide an implementation of ``cursor.execute(statement,
2212 parameters)``."""
2213
2214 raise NotImplementedError()
2215
2216 def do_execute_no_params(
2217 self,
2218 cursor: DBAPICursor,
2219 statement: str,
2220 context: Optional[ExecutionContext] = None,
2221 ) -> None:
2222 """Provide an implementation of ``cursor.execute(statement)``.
2223
2224 The parameter collection should not be sent.
2225
2226 """
2227
2228 raise NotImplementedError()
2229
2230 def is_disconnect(
2231 self,
2232 e: DBAPIModule.Error,
2233 connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]],
2234 cursor: Optional[DBAPICursor],
2235 ) -> bool:
2236 """Return True if the given DB-API error indicates an invalid
2237 connection"""
2238
2239 raise NotImplementedError()
2240
2241 def connect(self, *cargs: Any, **cparams: Any) -> DBAPIConnection:
2242 r"""Establish a connection using this dialect's DBAPI.
2243
2244 The default implementation of this method is::
2245
2246 def connect(self, *cargs, **cparams):
2247 return self.dbapi.connect(*cargs, **cparams)
2248
2249 The ``*cargs, **cparams`` parameters are generated directly
2250 from this dialect's :meth:`.Dialect.create_connect_args` method.
2251
2252 This method may be used for dialects that need to perform programmatic
2253 per-connection steps when a new connection is procured from the
2254 DBAPI.
2255
2256
2257 :param \*cargs: positional parameters returned from the
2258 :meth:`.Dialect.create_connect_args` method
2259
2260 :param \*\*cparams: keyword parameters returned from the
2261 :meth:`.Dialect.create_connect_args` method.
2262
2263 :return: a DBAPI connection, typically from the :pep:`249` module
2264 level ``.connect()`` function.
2265
2266 .. seealso::
2267
2268 :meth:`.Dialect.create_connect_args`
2269
2270 :meth:`.Dialect.on_connect`
2271
2272 """
2273 raise NotImplementedError()
2274
2275 def on_connect_url(self, url: URL) -> Optional[Callable[[Any], Any]]:
2276 """return a callable which sets up a newly created DBAPI connection.
2277
2278 This method is a new hook that supersedes the
2279 :meth:`_engine.Dialect.on_connect` method when implemented by a
2280 dialect. When not implemented by a dialect, it invokes the
2281 :meth:`_engine.Dialect.on_connect` method directly to maintain
2282 compatibility with existing dialects. There is no deprecation
2283 for :meth:`_engine.Dialect.on_connect` expected.
2284
2285 The callable should accept a single argument "conn" which is the
2286 DBAPI connection itself. The inner callable has no
2287 return value.
2288
2289 E.g.::
2290
2291 class MyDialect(default.DefaultDialect):
2292 # ...
2293
2294 def on_connect_url(self, url):
2295 def do_on_connect(connection):
2296 connection.execute("SET SPECIAL FLAGS etc")
2297
2298 return do_on_connect
2299
2300 This is used to set dialect-wide per-connection options such as
2301 isolation modes, Unicode modes, etc.
2302
2303 This method differs from :meth:`_engine.Dialect.on_connect` in that
2304 it is passed the :class:`_engine.URL` object that's relevant to the
2305 connect args. Normally the only way to get this is from the
2306 :meth:`_engine.Dialect.on_connect` hook is to look on the
2307 :class:`_engine.Engine` itself, however this URL object may have been
2308 replaced by plugins.
2309
2310 .. note::
2311
2312 The default implementation of
2313 :meth:`_engine.Dialect.on_connect_url` is to invoke the
2314 :meth:`_engine.Dialect.on_connect` method. Therefore if a dialect
2315 implements this method, the :meth:`_engine.Dialect.on_connect`
2316 method **will not be called** unless the overriding dialect calls
2317 it directly from here.
2318
2319 .. versionadded:: 1.4.3 added :meth:`_engine.Dialect.on_connect_url`
2320 which normally calls into :meth:`_engine.Dialect.on_connect`.
2321
2322 :param url: a :class:`_engine.URL` object representing the
2323 :class:`_engine.URL` that was passed to the
2324 :meth:`_engine.Dialect.create_connect_args` method.
2325
2326 :return: a callable that accepts a single DBAPI connection as an
2327 argument, or None.
2328
2329 .. seealso::
2330
2331 :meth:`_engine.Dialect.on_connect`
2332
2333 """
2334 return self.on_connect()
2335
2336 def on_connect(self) -> Optional[Callable[[Any], None]]:
2337 """return a callable which sets up a newly created DBAPI connection.
2338
2339 The callable should accept a single argument "conn" which is the
2340 DBAPI connection itself. The inner callable has no
2341 return value.
2342
2343 E.g.::
2344
2345 class MyDialect(default.DefaultDialect):
2346 # ...
2347
2348 def on_connect(self):
2349 def do_on_connect(connection):
2350 connection.execute("SET SPECIAL FLAGS etc")
2351
2352 return do_on_connect
2353
2354 This is used to set dialect-wide per-connection options such as
2355 isolation modes, Unicode modes, etc.
2356
2357 The "do_on_connect" callable is invoked by using the
2358 :meth:`_events.PoolEvents.connect` event
2359 hook, then unwrapping the DBAPI connection and passing it into the
2360 callable.
2361
2362 .. versionchanged:: 1.4 the on_connect hook is no longer called twice
2363 for the first connection of a dialect. The on_connect hook is still
2364 called before the :meth:`_engine.Dialect.initialize` method however.
2365
2366 .. versionchanged:: 1.4.3 the on_connect hook is invoked from a new
2367 method on_connect_url that passes the URL that was used to create
2368 the connect args. Dialects can implement on_connect_url instead
2369 of on_connect if they need the URL object that was used for the
2370 connection in order to get additional context.
2371
2372 If None is returned, no event listener is generated.
2373
2374 :return: a callable that accepts a single DBAPI connection as an
2375 argument, or None.
2376
2377 .. seealso::
2378
2379 :meth:`.Dialect.connect` - allows the DBAPI ``connect()`` sequence
2380 itself to be controlled.
2381
2382 :meth:`.Dialect.on_connect_url` - supersedes
2383 :meth:`.Dialect.on_connect` to also receive the
2384 :class:`_engine.URL` object in context.
2385
2386 """
2387 return None
2388
2389 def reset_isolation_level(self, dbapi_connection: DBAPIConnection) -> None:
2390 """Given a DBAPI connection, revert its isolation to the default.
2391
2392 Note that this is a dialect-level method which is used as part
2393 of the implementation of the :class:`_engine.Connection` and
2394 :class:`_engine.Engine`
2395 isolation level facilities; these APIs should be preferred for
2396 most typical use cases.
2397
2398 .. seealso::
2399
2400 :meth:`_engine.Connection.get_isolation_level`
2401 - view current level
2402
2403 :attr:`_engine.Connection.default_isolation_level`
2404 - view default level
2405
2406 :paramref:`.Connection.execution_options.isolation_level` -
2407 set per :class:`_engine.Connection` isolation level
2408
2409 :paramref:`_sa.create_engine.isolation_level` -
2410 set per :class:`_engine.Engine` isolation level
2411
2412 """
2413
2414 raise NotImplementedError()
2415
2416 def set_isolation_level(
2417 self, dbapi_connection: DBAPIConnection, level: IsolationLevel
2418 ) -> None:
2419 """Given a DBAPI connection, set its isolation level.
2420
2421 Note that this is a dialect-level method which is used as part
2422 of the implementation of the :class:`_engine.Connection` and
2423 :class:`_engine.Engine`
2424 isolation level facilities; these APIs should be preferred for
2425 most typical use cases.
2426
2427 If the dialect also implements the
2428 :meth:`.Dialect.get_isolation_level_values` method, then the given
2429 level is guaranteed to be one of the string names within that sequence,
2430 and the method will not need to anticipate a lookup failure.
2431
2432 .. seealso::
2433
2434 :meth:`_engine.Connection.get_isolation_level`
2435 - view current level
2436
2437 :attr:`_engine.Connection.default_isolation_level`
2438 - view default level
2439
2440 :paramref:`.Connection.execution_options.isolation_level` -
2441 set per :class:`_engine.Connection` isolation level
2442
2443 :paramref:`_sa.create_engine.isolation_level` -
2444 set per :class:`_engine.Engine` isolation level
2445
2446 """
2447
2448 raise NotImplementedError()
2449
2450 def get_isolation_level(
2451 self, dbapi_connection: DBAPIConnection
2452 ) -> IsolationLevel:
2453 """Given a DBAPI connection, return its isolation level.
2454
2455 When working with a :class:`_engine.Connection` object,
2456 the corresponding
2457 DBAPI connection may be procured using the
2458 :attr:`_engine.Connection.connection` accessor.
2459
2460 Note that this is a dialect-level method which is used as part
2461 of the implementation of the :class:`_engine.Connection` and
2462 :class:`_engine.Engine` isolation level facilities;
2463 these APIs should be preferred for most typical use cases.
2464
2465
2466 .. seealso::
2467
2468 :meth:`_engine.Connection.get_isolation_level`
2469 - view current level
2470
2471 :attr:`_engine.Connection.default_isolation_level`
2472 - view default level
2473
2474 :paramref:`.Connection.execution_options.isolation_level` -
2475 set per :class:`_engine.Connection` isolation level
2476
2477 :paramref:`_sa.create_engine.isolation_level` -
2478 set per :class:`_engine.Engine` isolation level
2479
2480
2481 """
2482
2483 raise NotImplementedError()
2484
2485 def detect_autocommit_setting(self, dbapi_conn: DBAPIConnection) -> bool:
2486 """Detect the current autocommit setting for a DBAPI connection.
2487
2488 :param dbapi_connection: a DBAPI connection object
2489 :return: True if autocommit is enabled, False if disabled
2490 :rtype: bool
2491
2492 This method inspects the given DBAPI connection to determine
2493 whether autocommit mode is currently enabled. The specific
2494 mechanism for detecting autocommit varies by database dialect
2495 and DBAPI driver, however it should be done **without** network
2496 round trips.
2497
2498 .. note::
2499
2500 Not all dialects support autocommit detection. Dialects
2501 that do not support this feature will raise
2502 :exc:`NotImplementedError`.
2503
2504 """
2505 raise NotImplementedError(
2506 "This dialect cannot detect autocommit on a DBAPI connection"
2507 )
2508
2509 def get_default_isolation_level(
2510 self, dbapi_conn: DBAPIConnection
2511 ) -> IsolationLevel:
2512 """Given a DBAPI connection, return its isolation level, or
2513 a default isolation level if one cannot be retrieved.
2514
2515 This method may only raise NotImplementedError and
2516 **must not raise any other exception**, as it is used implicitly upon
2517 first connect.
2518
2519 The method **must return a value** for a dialect that supports
2520 isolation level settings, as this level is what will be reverted
2521 towards when a per-connection isolation level change is made.
2522
2523 The method defaults to using the :meth:`.Dialect.get_isolation_level`
2524 method unless overridden by a dialect.
2525
2526 """
2527 raise NotImplementedError()
2528
2529 def get_isolation_level_values(
2530 self, dbapi_conn: DBAPIConnection
2531 ) -> Sequence[IsolationLevel]:
2532 """return a sequence of string isolation level names that are accepted
2533 by this dialect.
2534
2535 The available names should use the following conventions:
2536
2537 * use UPPERCASE names. isolation level methods will accept lowercase
2538 names but these are normalized into UPPERCASE before being passed
2539 along to the dialect.
2540 * separate words should be separated by spaces, not underscores, e.g.
2541 ``REPEATABLE READ``. isolation level names will have underscores
2542 converted to spaces before being passed along to the dialect.
2543 * The names for the four standard isolation names to the extent that
2544 they are supported by the backend should be ``READ UNCOMMITTED``,
2545 ``READ COMMITTED``, ``REPEATABLE READ``, ``SERIALIZABLE``
2546 * if the dialect supports an autocommit option it should be provided
2547 using the isolation level name ``AUTOCOMMIT``.
2548 * Other isolation modes may also be present, provided that they
2549 are named in UPPERCASE and use spaces not underscores.
2550
2551 This function is used so that the default dialect can check that
2552 a given isolation level parameter is valid, else raises an
2553 :class:`_exc.ArgumentError`.
2554
2555 A DBAPI connection is passed to the method, in the unlikely event that
2556 the dialect needs to interrogate the connection itself to determine
2557 this list, however it is expected that most backends will return
2558 a hardcoded list of values. If the dialect supports "AUTOCOMMIT",
2559 that value should also be present in the sequence returned.
2560
2561 The method raises ``NotImplementedError`` by default. If a dialect
2562 does not implement this method, then the default dialect will not
2563 perform any checking on a given isolation level value before passing
2564 it onto the :meth:`.Dialect.set_isolation_level` method. This is
2565 to allow backwards-compatibility with third party dialects that may
2566 not yet be implementing this method.
2567
2568 .. versionadded:: 2.0
2569
2570 """
2571 raise NotImplementedError()
2572
2573 def _assert_and_set_isolation_level(
2574 self, dbapi_conn: DBAPIConnection, level: IsolationLevel
2575 ) -> None:
2576 raise NotImplementedError()
2577
2578 @classmethod
2579 def get_dialect_cls(cls, url: URL) -> Type[Dialect]:
2580 """Given a URL, return the :class:`.Dialect` that will be used.
2581
2582 This is a hook that allows an external plugin to provide functionality
2583 around an existing dialect, by allowing the plugin to be loaded
2584 from the url based on an entrypoint, and then the plugin returns
2585 the actual dialect to be used.
2586
2587 By default this just returns the cls.
2588
2589 """
2590 return cls
2591
2592 @classmethod
2593 def get_async_dialect_cls(cls, url: URL) -> Type[Dialect]:
2594 """Given a URL, return the :class:`.Dialect` that will be used by
2595 an async engine.
2596
2597 By default this is an alias of :meth:`.Dialect.get_dialect_cls` and
2598 just returns the cls. It may be used if a dialect provides
2599 both a sync and async version under the same name, like the
2600 ``psycopg`` driver.
2601
2602 .. versionadded:: 2
2603
2604 .. seealso::
2605
2606 :meth:`.Dialect.get_dialect_cls`
2607
2608 """
2609 return cls.get_dialect_cls(url)
2610
2611 @classmethod
2612 def load_provisioning(cls) -> None:
2613 """set up the provision.py module for this dialect.
2614
2615 For dialects that include a provision.py module that sets up
2616 provisioning followers, this method should initiate that process.
2617
2618 A typical implementation would be::
2619
2620 @classmethod
2621 def load_provisioning(cls):
2622 __import__("mydialect.provision")
2623
2624 The default method assumes a module named ``provision.py`` inside
2625 the owning package of the current dialect, based on the ``__module__``
2626 attribute::
2627
2628 @classmethod
2629 def load_provisioning(cls):
2630 package = ".".join(cls.__module__.split(".")[0:-1])
2631 try:
2632 __import__(package + ".provision")
2633 except ImportError:
2634 pass
2635
2636 """
2637
2638 @classmethod
2639 def engine_created(cls, engine: Engine) -> None:
2640 """A convenience hook called before returning the final
2641 :class:`_engine.Engine`.
2642
2643 If the dialect returned a different class from the
2644 :meth:`.get_dialect_cls`
2645 method, then the hook is called on both classes, first on
2646 the dialect class returned by the :meth:`.get_dialect_cls` method and
2647 then on the class on which the method was called.
2648
2649 The hook should be used by dialects and/or wrappers to apply special
2650 events to the engine or its components. In particular, it allows
2651 a dialect-wrapping class to apply dialect-level events.
2652
2653 """
2654
2655 def get_driver_connection(self, connection: DBAPIConnection) -> Any:
2656 """Returns the connection object as returned by the external driver
2657 package.
2658
2659 For normal dialects that use a DBAPI compliant driver this call
2660 will just return the ``connection`` passed as argument.
2661 For dialects that instead adapt a non DBAPI compliant driver, like
2662 when adapting an asyncio driver, this call will return the
2663 connection-like object as returned by the driver.
2664
2665 .. versionadded:: 1.4.24
2666
2667 """
2668 raise NotImplementedError()
2669
2670 def set_engine_execution_options(
2671 self, engine: Engine, opts: CoreExecuteOptionsParameter
2672 ) -> None:
2673 """Establish execution options for a given engine.
2674
2675 This is implemented by :class:`.DefaultDialect` to establish
2676 event hooks for new :class:`.Connection` instances created
2677 by the given :class:`.Engine` which will then invoke the
2678 :meth:`.Dialect.set_connection_execution_options` method for that
2679 connection.
2680
2681 """
2682 raise NotImplementedError()
2683
2684 def set_connection_execution_options(
2685 self, connection: Connection, opts: CoreExecuteOptionsParameter
2686 ) -> None:
2687 """Establish execution options for a given connection.
2688
2689 This is implemented by :class:`.DefaultDialect` in order to implement
2690 the :paramref:`_engine.Connection.execution_options.isolation_level`
2691 execution option. Dialects can intercept various execution options
2692 which may need to modify state on a particular DBAPI connection.
2693
2694 .. versionadded:: 1.4
2695
2696 """
2697 raise NotImplementedError()
2698
2699 def get_dialect_pool_class(self, url: URL) -> Type[Pool]:
2700 """return a Pool class to use for a given URL"""
2701 raise NotImplementedError()
2702
2703 def validate_identifier(self, ident: str) -> None:
2704 """Validates an identifier name, raising an exception if invalid"""
2705
2706
2707class CreateEnginePlugin:
2708 """A set of hooks intended to augment the construction of an
2709 :class:`_engine.Engine` object based on entrypoint names in a URL.
2710
2711 The purpose of :class:`_engine.CreateEnginePlugin` is to allow third-party
2712 systems to apply engine, pool and dialect level event listeners without
2713 the need for the target application to be modified; instead, the plugin
2714 names can be added to the database URL. Target applications for
2715 :class:`_engine.CreateEnginePlugin` include:
2716
2717 * connection and SQL performance tools, e.g. which use events to track
2718 number of checkouts and/or time spent with statements
2719
2720 * connectivity plugins such as proxies
2721
2722 A rudimentary :class:`_engine.CreateEnginePlugin` that attaches a logger
2723 to an :class:`_engine.Engine` object might look like::
2724
2725
2726 import logging
2727
2728 from sqlalchemy.engine import CreateEnginePlugin
2729 from sqlalchemy import event
2730
2731
2732 class LogCursorEventsPlugin(CreateEnginePlugin):
2733 def __init__(self, url, kwargs):
2734 # consume the parameter "log_cursor_logging_name" from the
2735 # URL query
2736 logging_name = url.query.get(
2737 "log_cursor_logging_name", "log_cursor"
2738 )
2739
2740 self.log = logging.getLogger(logging_name)
2741
2742 def update_url(self, url):
2743 "update the URL to one that no longer includes our parameters"
2744 return url.difference_update_query(["log_cursor_logging_name"])
2745
2746 def engine_created(self, engine):
2747 "attach an event listener after the new Engine is constructed"
2748 event.listen(engine, "before_cursor_execute", self._log_event)
2749
2750 def _log_event(
2751 self,
2752 conn,
2753 cursor,
2754 statement,
2755 parameters,
2756 context,
2757 executemany,
2758 ):
2759
2760 self.log.info("Plugin logged cursor event: %s", statement)
2761
2762 Plugins are registered using entry points in a similar way as that
2763 of dialects::
2764
2765 entry_points = {
2766 "sqlalchemy.plugins": [
2767 "log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin"
2768 ]
2769 }
2770
2771 A plugin that uses the above names would be invoked from a database
2772 URL as in::
2773
2774 from sqlalchemy import create_engine
2775
2776 engine = create_engine(
2777 "mysql+pymysql://scott:tiger@localhost/test?"
2778 "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger"
2779 )
2780
2781 The ``plugin`` URL parameter supports multiple instances, so that a URL
2782 may specify multiple plugins; they are loaded in the order stated
2783 in the URL::
2784
2785 engine = create_engine(
2786 "mysql+pymysql://scott:tiger@localhost/test?"
2787 "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three"
2788 )
2789
2790 The plugin names may also be passed directly to :func:`_sa.create_engine`
2791 using the :paramref:`_sa.create_engine.plugins` argument::
2792
2793 engine = create_engine(
2794 "mysql+pymysql://scott:tiger@localhost/test", plugins=["myplugin"]
2795 )
2796
2797 A plugin may consume plugin-specific arguments from the
2798 :class:`_engine.URL` object as well as the ``kwargs`` dictionary, which is
2799 the dictionary of arguments passed to the :func:`_sa.create_engine`
2800 call. "Consuming" these arguments includes that they must be removed
2801 when the plugin initializes, so that the arguments are not passed along
2802 to the :class:`_engine.Dialect` constructor, where they will raise an
2803 :class:`_exc.ArgumentError` because they are not known by the dialect.
2804
2805 As of version 1.4 of SQLAlchemy, arguments should continue to be consumed
2806 from the ``kwargs`` dictionary directly, by removing the values with a
2807 method such as ``dict.pop``. Arguments from the :class:`_engine.URL` object
2808 should be consumed by implementing the
2809 :meth:`_engine.CreateEnginePlugin.update_url` method, returning a new copy
2810 of the :class:`_engine.URL` with plugin-specific parameters removed::
2811
2812 class MyPlugin(CreateEnginePlugin):
2813 def __init__(self, url, kwargs):
2814 self.my_argument_one = url.query["my_argument_one"]
2815 self.my_argument_two = url.query["my_argument_two"]
2816 self.my_argument_three = kwargs.pop("my_argument_three", None)
2817
2818 def update_url(self, url):
2819 return url.difference_update_query(
2820 ["my_argument_one", "my_argument_two"]
2821 )
2822
2823 Arguments like those illustrated above would be consumed from a
2824 :func:`_sa.create_engine` call such as::
2825
2826 from sqlalchemy import create_engine
2827
2828 engine = create_engine(
2829 "mysql+pymysql://scott:tiger@localhost/test?"
2830 "plugin=myplugin&my_argument_one=foo&my_argument_two=bar",
2831 my_argument_three="bat",
2832 )
2833
2834 .. versionchanged:: 1.4
2835
2836 The :class:`_engine.URL` object is now immutable; a
2837 :class:`_engine.CreateEnginePlugin` that needs to alter the
2838 :class:`_engine.URL` should implement the newly added
2839 :meth:`_engine.CreateEnginePlugin.update_url` method, which
2840 is invoked after the plugin is constructed.
2841
2842 For migration, construct the plugin in the following way, checking
2843 for the existence of the :meth:`_engine.CreateEnginePlugin.update_url`
2844 method to detect which version is running::
2845
2846 class MyPlugin(CreateEnginePlugin):
2847 def __init__(self, url, kwargs):
2848 if hasattr(CreateEnginePlugin, "update_url"):
2849 # detect the 1.4 API
2850 self.my_argument_one = url.query["my_argument_one"]
2851 self.my_argument_two = url.query["my_argument_two"]
2852 else:
2853 # detect the 1.3 and earlier API - mutate the
2854 # URL directly
2855 self.my_argument_one = url.query.pop("my_argument_one")
2856 self.my_argument_two = url.query.pop("my_argument_two")
2857
2858 self.my_argument_three = kwargs.pop("my_argument_three", None)
2859
2860 def update_url(self, url):
2861 # this method is only called in the 1.4 version
2862 return url.difference_update_query(
2863 ["my_argument_one", "my_argument_two"]
2864 )
2865
2866 .. seealso::
2867
2868 :ref:`change_5526` - overview of the :class:`_engine.URL` change which
2869 also includes notes regarding :class:`_engine.CreateEnginePlugin`.
2870
2871
2872 When the engine creation process completes and produces the
2873 :class:`_engine.Engine` object, it is again passed to the plugin via the
2874 :meth:`_engine.CreateEnginePlugin.engine_created` hook. In this hook, additional
2875 changes can be made to the engine, most typically involving setup of
2876 events (e.g. those defined in :ref:`core_event_toplevel`).
2877
2878 """ # noqa: E501
2879
2880 def __init__(self, url: URL, kwargs: Dict[str, Any]):
2881 """Construct a new :class:`.CreateEnginePlugin`.
2882
2883 The plugin object is instantiated individually for each call
2884 to :func:`_sa.create_engine`. A single :class:`_engine.
2885 Engine` will be
2886 passed to the :meth:`.CreateEnginePlugin.engine_created` method
2887 corresponding to this URL.
2888
2889 :param url: the :class:`_engine.URL` object. The plugin may inspect
2890 the :class:`_engine.URL` for arguments. Arguments used by the
2891 plugin should be removed, by returning an updated :class:`_engine.URL`
2892 from the :meth:`_engine.CreateEnginePlugin.update_url` method.
2893
2894 .. versionchanged:: 1.4
2895
2896 The :class:`_engine.URL` object is now immutable, so a
2897 :class:`_engine.CreateEnginePlugin` that needs to alter the
2898 :class:`_engine.URL` object should implement the
2899 :meth:`_engine.CreateEnginePlugin.update_url` method.
2900
2901 :param kwargs: The keyword arguments passed to
2902 :func:`_sa.create_engine`.
2903
2904 """
2905 self.url = url
2906
2907 def update_url(self, url: URL) -> URL:
2908 """Update the :class:`_engine.URL`.
2909
2910 A new :class:`_engine.URL` should be returned. This method is
2911 typically used to consume configuration arguments from the
2912 :class:`_engine.URL` which must be removed, as they will not be
2913 recognized by the dialect. The
2914 :meth:`_engine.URL.difference_update_query` method is available
2915 to remove these arguments. See the docstring at
2916 :class:`_engine.CreateEnginePlugin` for an example.
2917
2918
2919 .. versionadded:: 1.4
2920
2921 """
2922 raise NotImplementedError()
2923
2924 def handle_dialect_kwargs(
2925 self, dialect_cls: Type[Dialect], dialect_args: Dict[str, Any]
2926 ) -> None:
2927 """parse and modify dialect kwargs"""
2928
2929 def handle_pool_kwargs(
2930 self, pool_cls: Type[Pool], pool_args: Dict[str, Any]
2931 ) -> None:
2932 """parse and modify pool kwargs"""
2933
2934 def engine_created(self, engine: Engine) -> None:
2935 """Receive the :class:`_engine.Engine`
2936 object when it is fully constructed.
2937
2938 The plugin may make additional changes to the engine, such as
2939 registering engine or connection pool events.
2940
2941 """
2942
2943
2944class ExecutionContext:
2945 """A messenger object for a Dialect that corresponds to a single
2946 execution.
2947
2948 """
2949
2950 engine: Engine
2951 """engine which the Connection is associated with"""
2952
2953 connection: Connection
2954 """Connection object which can be freely used by default value
2955 generators to execute SQL. This Connection should reference the
2956 same underlying connection/transactional resources of
2957 root_connection."""
2958
2959 root_connection: Connection
2960 """Connection object which is the source of this ExecutionContext."""
2961
2962 dialect: Dialect
2963 """dialect which created this ExecutionContext."""
2964
2965 cursor: DBAPICursor
2966 """DB-API cursor procured from the connection"""
2967
2968 compiled: Optional[Compiled]
2969 """if passed to constructor, sqlalchemy.engine.base.Compiled object
2970 being executed"""
2971
2972 statement: str
2973 """string version of the statement to be executed. Is either
2974 passed to the constructor, or must be created from the
2975 sql.Compiled object by the time pre_exec() has completed."""
2976
2977 invoked_statement: Optional[Executable]
2978 """The Executable statement object that was given in the first place.
2979
2980 This should be structurally equivalent to compiled.statement, but not
2981 necessarily the same object as in a caching scenario the compiled form
2982 will have been extracted from the cache.
2983
2984 """
2985
2986 parameters: _AnyMultiExecuteParams
2987 """bind parameters passed to the execute() or exec_driver_sql() methods.
2988
2989 These are always stored as a list of parameter entries. A single-element
2990 list corresponds to a ``cursor.execute()`` call and a multiple-element
2991 list corresponds to ``cursor.executemany()``, except in the case
2992 of :attr:`.ExecuteStyle.INSERTMANYVALUES` which will use
2993 ``cursor.execute()`` one or more times.
2994
2995 """
2996
2997 no_parameters: bool
2998 """True if the execution style does not use parameters"""
2999
3000 isinsert: bool
3001 """True if the statement is an INSERT."""
3002
3003 isupdate: bool
3004 """True if the statement is an UPDATE."""
3005
3006 execute_style: ExecuteStyle
3007 """the style of DBAPI cursor method that will be used to execute
3008 a statement.
3009
3010 .. versionadded:: 2.0
3011
3012 """
3013
3014 executemany: bool
3015 """True if the context has a list of more than one parameter set.
3016
3017 Historically this attribute links to whether ``cursor.execute()`` or
3018 ``cursor.executemany()`` will be used. It also can now mean that
3019 "insertmanyvalues" may be used which indicates one or more
3020 ``cursor.execute()`` calls.
3021
3022 """
3023
3024 prefetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]]
3025 """a list of Column objects for which a client-side default
3026 was fired off. Applies to inserts and updates."""
3027
3028 postfetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]]
3029 """a list of Column objects for which a server-side default or
3030 inline SQL expression value was fired off. Applies to inserts
3031 and updates."""
3032
3033 execution_options: _ExecuteOptions
3034 """Execution options associated with the current statement execution"""
3035
3036 @classmethod
3037 def _init_ddl(
3038 cls,
3039 dialect: Dialect,
3040 connection: Connection,
3041 dbapi_connection: PoolProxiedConnection,
3042 execution_options: _ExecuteOptions,
3043 compiled_ddl: DDLCompiler,
3044 ) -> ExecutionContext:
3045 raise NotImplementedError()
3046
3047 @classmethod
3048 def _init_compiled(
3049 cls,
3050 dialect: Dialect,
3051 connection: Connection,
3052 dbapi_connection: PoolProxiedConnection,
3053 execution_options: _ExecuteOptions,
3054 compiled: SQLCompiler,
3055 parameters: _CoreMultiExecuteParams,
3056 invoked_statement: Executable,
3057 extracted_parameters: Optional[Sequence[BindParameter[Any]]],
3058 cache_hit: CacheStats = CacheStats.CACHING_DISABLED,
3059 ) -> ExecutionContext:
3060 raise NotImplementedError()
3061
3062 @classmethod
3063 def _init_statement(
3064 cls,
3065 dialect: Dialect,
3066 connection: Connection,
3067 dbapi_connection: PoolProxiedConnection,
3068 execution_options: _ExecuteOptions,
3069 statement: str,
3070 parameters: _DBAPIMultiExecuteParams,
3071 ) -> ExecutionContext:
3072 raise NotImplementedError()
3073
3074 @classmethod
3075 def _init_default(
3076 cls,
3077 dialect: Dialect,
3078 connection: Connection,
3079 dbapi_connection: PoolProxiedConnection,
3080 execution_options: _ExecuteOptions,
3081 ) -> ExecutionContext:
3082 raise NotImplementedError()
3083
3084 def _exec_default(
3085 self,
3086 column: Optional[Column[Any]],
3087 default: DefaultGenerator,
3088 type_: Optional[TypeEngine[Any]],
3089 ) -> Any:
3090 raise NotImplementedError()
3091
3092 def _prepare_set_input_sizes(
3093 self,
3094 ) -> Optional[List[Tuple[str, Any, TypeEngine[Any]]]]:
3095 raise NotImplementedError()
3096
3097 def _get_cache_stats(self) -> str:
3098 raise NotImplementedError()
3099
3100 def _setup_result_proxy(self) -> CursorResult[Any]:
3101 raise NotImplementedError()
3102
3103 def fire_sequence(self, seq: Sequence_SchemaItem, type_: Integer) -> int:
3104 """given a :class:`.Sequence`, invoke it and return the next int
3105 value"""
3106 raise NotImplementedError()
3107
3108 def create_cursor(self) -> DBAPICursor:
3109 """Return a new cursor generated from this ExecutionContext's
3110 connection.
3111
3112 Some dialects may wish to change the behavior of
3113 connection.cursor(), such as postgresql which may return a PG
3114 "server side" cursor.
3115 """
3116
3117 raise NotImplementedError()
3118
3119 def pre_exec(self) -> None:
3120 """Called before an execution of a compiled statement.
3121
3122 If a compiled statement was passed to this ExecutionContext,
3123 the `statement` and `parameters` datamembers must be
3124 initialized after this statement is complete.
3125 """
3126
3127 raise NotImplementedError()
3128
3129 def get_out_parameter_values(
3130 self, out_param_names: Sequence[str]
3131 ) -> Sequence[Any]:
3132 """Return a sequence of OUT parameter values from a cursor.
3133
3134 For dialects that support OUT parameters, this method will be called
3135 when there is a :class:`.SQLCompiler` object which has the
3136 :attr:`.SQLCompiler.has_out_parameters` flag set. This flag in turn
3137 will be set to True if the statement itself has :class:`.BindParameter`
3138 objects that have the ``.isoutparam`` flag set which are consumed by
3139 the :meth:`.SQLCompiler.visit_bindparam` method. If the dialect
3140 compiler produces :class:`.BindParameter` objects with ``.isoutparam``
3141 set which are not handled by :meth:`.SQLCompiler.visit_bindparam`, it
3142 should set this flag explicitly.
3143
3144 The list of names that were rendered for each bound parameter
3145 is passed to the method. The method should then return a sequence of
3146 values corresponding to the list of parameter objects. Unlike in
3147 previous SQLAlchemy versions, the values can be the **raw values** from
3148 the DBAPI; the execution context will apply the appropriate type
3149 handler based on what's present in self.compiled.binds and update the
3150 values. The processed dictionary will then be made available via the
3151 ``.out_parameters`` collection on the result object. Note that
3152 SQLAlchemy 1.4 has multiple kinds of result object as part of the 2.0
3153 transition.
3154
3155 .. versionadded:: 1.4 - added
3156 :meth:`.ExecutionContext.get_out_parameter_values`, which is invoked
3157 automatically by the :class:`.DefaultExecutionContext` when there
3158 are :class:`.BindParameter` objects with the ``.isoutparam`` flag
3159 set. This replaces the practice of setting out parameters within
3160 the now-removed ``get_result_proxy()`` method.
3161
3162 """
3163 raise NotImplementedError()
3164
3165 def post_exec(self) -> None:
3166 """Called after the execution of a compiled statement.
3167
3168 If a compiled statement was passed to this ExecutionContext,
3169 the `last_insert_ids`, `last_inserted_params`, etc.
3170 datamembers should be available after this method completes.
3171 """
3172
3173 raise NotImplementedError()
3174
3175 def handle_dbapi_exception(self, e: BaseException) -> None:
3176 """Receive a DBAPI exception which occurred upon execute, result
3177 fetch, etc."""
3178
3179 raise NotImplementedError()
3180
3181 def lastrow_has_defaults(self) -> bool:
3182 """Return True if the last INSERT or UPDATE row contained
3183 inlined or database-side defaults.
3184 """
3185
3186 raise NotImplementedError()
3187
3188 def get_rowcount(self) -> Optional[int]:
3189 """Return the DBAPI ``cursor.rowcount`` value, or in some
3190 cases an interpreted value.
3191
3192 See :attr:`_engine.CursorResult.rowcount` for details on this.
3193
3194 """
3195
3196 raise NotImplementedError()
3197
3198 def fetchall_for_returning(self, cursor: DBAPICursor) -> Sequence[Any]:
3199 """For a RETURNING result, deliver cursor.fetchall() from the
3200 DBAPI cursor.
3201
3202 This is a dialect-specific hook for dialects that have special
3203 considerations when calling upon the rows delivered for a
3204 "RETURNING" statement. Default implementation is
3205 ``cursor.fetchall()``.
3206
3207 This hook is currently used only by the :term:`insertmanyvalues`
3208 feature. Dialects that don't set ``use_insertmanyvalues=True``
3209 don't need to consider this hook.
3210
3211 .. versionadded:: 2.0.10
3212
3213 """
3214 raise NotImplementedError()
3215
3216
3217class ConnectionEventsTarget(EventTarget):
3218 """An object which can accept events from :class:`.ConnectionEvents`.
3219
3220 Includes :class:`_engine.Connection` and :class:`_engine.Engine`.
3221
3222 .. versionadded:: 2.0
3223
3224 """
3225
3226 dispatch: dispatcher[ConnectionEventsTarget]
3227
3228
3229Connectable = ConnectionEventsTarget
3230
3231
3232class ExceptionContext:
3233 """Encapsulate information about an error condition in progress.
3234
3235 This object exists solely to be passed to the
3236 :meth:`_events.DialectEvents.handle_error` event,
3237 supporting an interface that
3238 can be extended without backwards-incompatibility.
3239
3240
3241 """
3242
3243 __slots__ = ()
3244
3245 dialect: Dialect
3246 """The :class:`_engine.Dialect` in use.
3247
3248 This member is present for all invocations of the event hook.
3249
3250 .. versionadded:: 2.0
3251
3252 """
3253
3254 connection: Optional[Connection]
3255 """The :class:`_engine.Connection` in use during the exception.
3256
3257 This member is present, except in the case of a failure when
3258 first connecting.
3259
3260 .. seealso::
3261
3262 :attr:`.ExceptionContext.engine`
3263
3264
3265 """
3266
3267 engine: Optional[Engine]
3268 """The :class:`_engine.Engine` in use during the exception.
3269
3270 This member is present in all cases except for when handling an error
3271 within the connection pool "pre-ping" process.
3272
3273 """
3274
3275 cursor: Optional[DBAPICursor]
3276 """The DBAPI cursor object.
3277
3278 May be None.
3279
3280 """
3281
3282 statement: Optional[str]
3283 """String SQL statement that was emitted directly to the DBAPI.
3284
3285 May be None.
3286
3287 """
3288
3289 parameters: Optional[_DBAPIAnyExecuteParams]
3290 """Parameter collection that was emitted directly to the DBAPI.
3291
3292 May be None.
3293
3294 """
3295
3296 original_exception: BaseException
3297 """The exception object which was caught.
3298
3299 This member is always present.
3300
3301 """
3302
3303 sqlalchemy_exception: Optional[StatementError]
3304 """The :class:`sqlalchemy.exc.StatementError` which wraps the original,
3305 and will be raised if exception handling is not circumvented by the event.
3306
3307 May be None, as not all exception types are wrapped by SQLAlchemy.
3308 For DBAPI-level exceptions that subclass the dbapi's Error class, this
3309 field will always be present.
3310
3311 """
3312
3313 chained_exception: Optional[BaseException]
3314 """The exception that was returned by the previous handler in the
3315 exception chain, if any.
3316
3317 If present, this exception will be the one ultimately raised by
3318 SQLAlchemy unless a subsequent handler replaces it.
3319
3320 May be None.
3321
3322 """
3323
3324 execution_context: Optional[ExecutionContext]
3325 """The :class:`.ExecutionContext` corresponding to the execution
3326 operation in progress.
3327
3328 This is present for statement execution operations, but not for
3329 operations such as transaction begin/end. It also is not present when
3330 the exception was raised before the :class:`.ExecutionContext`
3331 could be constructed.
3332
3333 Note that the :attr:`.ExceptionContext.statement` and
3334 :attr:`.ExceptionContext.parameters` members may represent a
3335 different value than that of the :class:`.ExecutionContext`,
3336 potentially in the case where a
3337 :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar
3338 modified the statement/parameters to be sent.
3339
3340 May be None.
3341
3342 """
3343
3344 is_disconnect: bool
3345 """Represent whether the exception as occurred represents a "disconnect"
3346 condition.
3347
3348 This flag will always be True or False within the scope of the
3349 :meth:`_events.DialectEvents.handle_error` handler.
3350
3351 SQLAlchemy will defer to this flag in order to determine whether or not
3352 the connection should be invalidated subsequently. That is, by
3353 assigning to this flag, a "disconnect" event which then results in
3354 a connection and pool invalidation can be invoked or prevented by
3355 changing this flag.
3356
3357
3358 .. note:: The pool "pre_ping" handler enabled using the
3359 :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not**
3360 consult this event before deciding if the "ping" returned false,
3361 as opposed to receiving an unhandled error. For this use case, the
3362 :ref:`legacy recipe based on engine_connect() may be used
3363 <pool_disconnects_pessimistic_custom>`. A future API allow more
3364 comprehensive customization of the "disconnect" detection mechanism
3365 across all functions.
3366
3367 """
3368
3369 invalidate_pool_on_disconnect: bool
3370 """Represent whether all connections in the pool should be invalidated
3371 when a "disconnect" condition is in effect.
3372
3373 Setting this flag to False within the scope of the
3374 :meth:`_events.DialectEvents.handle_error`
3375 event will have the effect such
3376 that the full collection of connections in the pool will not be
3377 invalidated during a disconnect; only the current connection that is the
3378 subject of the error will actually be invalidated.
3379
3380 The purpose of this flag is for custom disconnect-handling schemes where
3381 the invalidation of other connections in the pool is to be performed
3382 based on other conditions, or even on a per-connection basis.
3383
3384 """
3385
3386 is_pre_ping: bool
3387 """Indicates if this error is occurring within the "pre-ping" step
3388 performed when :paramref:`_sa.create_engine.pool_pre_ping` is set to
3389 ``True``. In this mode, the :attr:`.ExceptionContext.engine` attribute
3390 will be ``None``. The dialect in use is accessible via the
3391 :attr:`.ExceptionContext.dialect` attribute.
3392
3393 .. versionadded:: 2.0.5
3394
3395 """
3396
3397
3398class AdaptedConnection:
3399 """Interface of an adapted connection object to support the DBAPI protocol.
3400
3401 Used by asyncio dialects to provide a sync-style pep-249 facade on top
3402 of the asyncio connection/cursor API provided by the driver.
3403
3404 .. versionadded:: 1.4.24
3405
3406 """
3407
3408 __slots__ = ("_connection",)
3409
3410 _connection: AsyncIODBAPIConnection
3411
3412 @property
3413 def driver_connection(self) -> Any:
3414 """The connection object as returned by the driver after a connect."""
3415 return self._connection
3416
3417 def run_async(self, fn: Callable[[Any], Awaitable[_T]]) -> _T:
3418 """Run the awaitable returned by the given function, which is passed
3419 the raw asyncio driver connection.
3420
3421 This is used to invoke awaitable-only methods on the driver connection
3422 within the context of a "synchronous" method, like a connection
3423 pool event handler.
3424
3425 E.g.::
3426
3427 engine = create_async_engine(...)
3428
3429
3430 @event.listens_for(engine.sync_engine, "connect")
3431 def register_custom_types(
3432 dbapi_connection, # ...
3433 ):
3434 dbapi_connection.run_async(
3435 lambda connection: connection.set_type_codec(
3436 "MyCustomType", encoder, decoder, ...
3437 )
3438 )
3439
3440 .. versionadded:: 1.4.30
3441
3442 .. seealso::
3443
3444 :ref:`asyncio_events_run_async`
3445
3446 """
3447 return await_(fn(self._connection))
3448
3449 def __repr__(self) -> str:
3450 return "<AdaptedConnection %s>" % self._connection