Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/sqlalchemy/engine/interfaces.py : 62%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# engine/interfaces.py
2# Copyright (C) 2005-2020 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: http://www.opensource.org/licenses/mit-license.php
8"""Define core interfaces used by the engine system."""
10from .. import util
11from ..sql.compiler import Compiled # noqa
12from ..sql.compiler import TypeCompiler # noqa
15class Dialect(object):
16 """Define the behavior of a specific database and DB-API combination.
18 Any aspect of metadata definition, SQL query generation,
19 execution, result-set handling, or anything else which varies
20 between databases is defined under the general category of the
21 Dialect. The Dialect acts as a factory for other
22 database-specific object implementations including
23 ExecutionContext, Compiled, DefaultGenerator, and TypeEngine.
25 .. note:: Third party dialects should not subclass :class:`.Dialect`
26 directly. Instead, subclass :class:`.default.DefaultDialect` or
27 descendant class.
29 All dialects include the following attributes. There are many other
30 attributes that may be supported as well:
32 ``name``
33 identifying name for the dialect from a DBAPI-neutral point of view
34 (i.e. 'sqlite')
36 ``driver``
37 identifying name for the dialect's DBAPI
39 ``positional``
40 True if the paramstyle for this Dialect is positional.
42 ``paramstyle``
43 the paramstyle to be used (some DB-APIs support multiple
44 paramstyles).
46 ``encoding``
47 type of encoding to use for unicode, usually defaults to
48 'utf-8'.
50 ``statement_compiler``
51 a :class:`.Compiled` class used to compile SQL statements
53 ``ddl_compiler``
54 a :class:`.Compiled` class used to compile DDL statements
56 ``server_version_info``
57 a tuple containing a version number for the DB backend in use.
58 This value is only available for supporting dialects, and is
59 typically populated during the initial connection to the database.
61 ``default_schema_name``
62 the name of the default schema. This value is only available for
63 supporting dialects, and is typically populated during the
64 initial connection to the database.
66 ``execution_ctx_cls``
67 a :class:`.ExecutionContext` class used to handle statement execution
69 ``execute_sequence_format``
70 either the 'tuple' or 'list' type, depending on what cursor.execute()
71 accepts for the second argument (they vary).
73 ``preparer``
74 a :class:`~sqlalchemy.sql.compiler.IdentifierPreparer` class used to
75 quote identifiers.
77 ``supports_alter``
78 ``True`` if the database supports ``ALTER TABLE`` - used only for
79 generating foreign key constraints in certain circumstances
81 ``max_identifier_length``
82 The maximum length of identifier names.
84 ``supports_sane_rowcount``
85 Indicate whether the dialect properly implements rowcount for
86 ``UPDATE`` and ``DELETE`` statements.
88 ``supports_sane_multi_rowcount``
89 Indicate whether the dialect properly implements rowcount for
90 ``UPDATE`` and ``DELETE`` statements when executed via
91 executemany.
93 ``preexecute_autoincrement_sequences``
94 True if 'implicit' primary key functions must be executed separately
95 in order to get their value. This is currently oriented towards
96 PostgreSQL.
98 ``implicit_returning``
99 use RETURNING or equivalent during INSERT execution in order to load
100 newly generated primary keys and other column defaults in one execution,
101 which are then available via inserted_primary_key.
102 If an insert statement has returning() specified explicitly,
103 the "implicit" functionality is not used and inserted_primary_key
104 will not be available.
106 ``colspecs``
107 A dictionary of TypeEngine classes from sqlalchemy.types mapped
108 to subclasses that are specific to the dialect class. This
109 dictionary is class-level only and is not accessed from the
110 dialect instance itself.
112 ``supports_default_values``
113 Indicates if the construct ``INSERT INTO tablename DEFAULT
114 VALUES`` is supported
116 ``supports_sequences``
117 Indicates if the dialect supports CREATE SEQUENCE or similar.
119 ``sequences_optional``
120 If True, indicates if the "optional" flag on the Sequence() construct
121 should signal to not generate a CREATE SEQUENCE. Applies only to
122 dialects that support sequences. Currently used only to allow PostgreSQL
123 SERIAL to be used on a column that specifies Sequence() for usage on
124 other backends.
126 ``supports_native_enum``
127 Indicates if the dialect supports a native ENUM construct.
128 This will prevent types.Enum from generating a CHECK
129 constraint when that type is used.
131 ``supports_native_boolean``
132 Indicates if the dialect supports a native boolean construct.
133 This will prevent types.Boolean from generating a CHECK
134 constraint when that type is used.
136 ``dbapi_exception_translation_map``
137 A dictionary of names that will contain as values the names of
138 pep-249 exceptions ("IntegrityError", "OperationalError", etc)
139 keyed to alternate class names, to support the case where a
140 DBAPI has exception classes that aren't named as they are
141 referred to (e.g. IntegrityError = MyException). In the vast
142 majority of cases this dictionary is empty.
144 .. versionadded:: 1.0.5
146 """
148 _has_events = False
150 def create_connect_args(self, url):
151 """Build DB-API compatible connection arguments.
153 Given a :class:`.URL` object, returns a tuple
154 consisting of a ``(*args, **kwargs)`` suitable to send directly
155 to the dbapi's connect function. The arguments are sent to the
156 :meth:`.Dialect.connect` method which then runs the DBAPI-level
157 ``connect()`` function.
159 The method typically makes use of the
160 :meth:`.URL.translate_connect_args`
161 method in order to generate a dictionary of options.
163 The default implementation is::
165 def create_connect_args(self, url):
166 opts = url.translate_connect_args()
167 opts.update(url.query)
168 return [[], opts]
170 :param url: a :class:`.URL` object
172 :return: a tuple of ``(*args, **kwargs)`` which will be passed to the
173 :meth:`.Dialect.connect` method.
175 .. seealso::
177 :meth:`.URL.translate_connect_args`
179 """
181 raise NotImplementedError()
183 @classmethod
184 def type_descriptor(cls, typeobj):
185 """Transform a generic type to a dialect-specific type.
187 Dialect classes will usually use the
188 :func:`_types.adapt_type` function in the types module to
189 accomplish this.
191 The returned result is cached *per dialect class* so can
192 contain no dialect-instance state.
194 """
196 raise NotImplementedError()
198 def initialize(self, connection):
199 """Called during strategized creation of the dialect with a
200 connection.
202 Allows dialects to configure options based on server version info or
203 other properties.
205 The connection passed here is a SQLAlchemy Connection object,
206 with full capabilities.
208 The initialize() method of the base dialect should be called via
209 super().
211 """
213 pass
215 def reflecttable(
216 self, connection, table, include_columns, exclude_columns, resolve_fks
217 ):
218 """Load table description from the database.
220 Given a :class:`_engine.Connection` and a
221 :class:`~sqlalchemy.schema.Table` object, reflect its columns and
222 properties from the database.
224 The implementation of this method is provided by
225 :meth:`.DefaultDialect.reflecttable`, which makes use of
226 :class:`_reflection.Inspector` to retrieve column information.
228 Dialects should **not** seek to implement this method, and should
229 instead implement individual schema inspection operations such as
230 :meth:`.Dialect.get_columns`, :meth:`.Dialect.get_pk_constraint`,
231 etc.
233 """
235 raise NotImplementedError()
237 def get_columns(self, connection, table_name, schema=None, **kw):
238 """Return information about columns in `table_name`.
240 Given a :class:`_engine.Connection`, a string
241 `table_name`, and an optional string `schema`, return column
242 information as a list of dictionaries with these keys:
244 name
245 the column's name
247 type
248 [sqlalchemy.types#TypeEngine]
250 nullable
251 boolean
253 default
254 the column's default value
256 autoincrement
257 boolean
259 sequence
260 a dictionary of the form
261 {'name' : str, 'start' :int, 'increment': int, 'minvalue': int,
262 'maxvalue': int, 'nominvalue': bool, 'nomaxvalue': bool,
263 'cycle': bool, 'cache': int, 'order': bool}
265 Additional column attributes may be present.
266 """
268 raise NotImplementedError()
270 @util.deprecated(
271 "0.8",
272 "The :meth:`.Dialect.get_primary_keys` method is deprecated and "
273 "will be removed in a future release. Please refer to the "
274 ":meth:`.Dialect.get_pk_constraint` method. ",
275 )
276 def get_primary_keys(self, connection, table_name, schema=None, **kw):
277 """Return information about primary keys in `table_name`.
279 """
281 raise NotImplementedError()
283 def get_pk_constraint(self, connection, table_name, schema=None, **kw):
284 """Return information about the primary key constraint on
285 table_name`.
287 Given a :class:`_engine.Connection`, a string
288 `table_name`, and an optional string `schema`, return primary
289 key information as a dictionary with these keys:
291 constrained_columns
292 a list of column names that make up the primary key
294 name
295 optional name of the primary key constraint.
297 """
298 raise NotImplementedError()
300 def get_foreign_keys(self, connection, table_name, schema=None, **kw):
301 """Return information about foreign_keys in `table_name`.
303 Given a :class:`_engine.Connection`, a string
304 `table_name`, and an optional string `schema`, return foreign
305 key information as a list of dicts with these keys:
307 name
308 the constraint's name
310 constrained_columns
311 a list of column names that make up the foreign key
313 referred_schema
314 the name of the referred schema
316 referred_table
317 the name of the referred table
319 referred_columns
320 a list of column names in the referred table that correspond to
321 constrained_columns
322 """
324 raise NotImplementedError()
326 def get_table_names(self, connection, schema=None, **kw):
327 """Return a list of table names for `schema`."""
329 raise NotImplementedError()
331 def get_temp_table_names(self, connection, schema=None, **kw):
332 """Return a list of temporary table names on the given connection,
333 if supported by the underlying backend.
335 """
337 raise NotImplementedError()
339 def get_view_names(self, connection, schema=None, **kw):
340 """Return a list of all view names available in the database.
342 schema:
343 Optional, retrieve names from a non-default schema.
344 """
346 raise NotImplementedError()
348 def get_temp_view_names(self, connection, schema=None, **kw):
349 """Return a list of temporary view names on the given connection,
350 if supported by the underlying backend.
352 """
354 raise NotImplementedError()
356 def get_view_definition(self, connection, view_name, schema=None, **kw):
357 """Return view definition.
359 Given a :class:`_engine.Connection`, a string
360 `view_name`, and an optional string `schema`, return the view
361 definition.
362 """
364 raise NotImplementedError()
366 def get_indexes(self, connection, table_name, schema=None, **kw):
367 """Return information about indexes in `table_name`.
369 Given a :class:`_engine.Connection`, a string
370 `table_name` and an optional string `schema`, return index
371 information as a list of dictionaries with these keys:
373 name
374 the index's name
376 column_names
377 list of column names in order
379 unique
380 boolean
381 """
383 raise NotImplementedError()
385 def get_unique_constraints(
386 self, connection, table_name, schema=None, **kw
387 ):
388 r"""Return information about unique constraints in `table_name`.
390 Given a string `table_name` and an optional string `schema`, return
391 unique constraint information as a list of dicts with these keys:
393 name
394 the unique constraint's name
396 column_names
397 list of column names in order
399 \**kw
400 other options passed to the dialect's get_unique_constraints()
401 method.
403 .. versionadded:: 0.9.0
405 """
407 raise NotImplementedError()
409 def get_check_constraints(self, connection, table_name, schema=None, **kw):
410 r"""Return information about check constraints in `table_name`.
412 Given a string `table_name` and an optional string `schema`, return
413 check constraint information as a list of dicts with these keys:
415 name
416 the check constraint's name
418 sqltext
419 the check constraint's SQL expression
421 \**kw
422 other options passed to the dialect's get_check_constraints()
423 method.
425 .. versionadded:: 1.1.0
427 """
429 raise NotImplementedError()
431 def get_table_comment(self, connection, table_name, schema=None, **kw):
432 r"""Return the "comment" for the table identified by `table_name`.
434 Given a string `table_name` and an optional string `schema`, return
435 table comment information as a dictionary with this key:
437 text
438 text of the comment
440 Raises ``NotImplementedError`` for dialects that don't support
441 comments.
443 .. versionadded:: 1.2
445 """
447 raise NotImplementedError()
449 def normalize_name(self, name):
450 """convert the given name to lowercase if it is detected as
451 case insensitive.
453 this method is only used if the dialect defines
454 requires_name_normalize=True.
456 """
457 raise NotImplementedError()
459 def denormalize_name(self, name):
460 """convert the given name to a case insensitive identifier
461 for the backend if it is an all-lowercase name.
463 this method is only used if the dialect defines
464 requires_name_normalize=True.
466 """
467 raise NotImplementedError()
469 def has_table(self, connection, table_name, schema=None):
470 """Check the existence of a particular table in the database.
472 Given a :class:`_engine.Connection` object and a string
473 `table_name`, return True if the given table (possibly within
474 the specified `schema`) exists in the database, False
475 otherwise.
476 """
478 raise NotImplementedError()
480 def has_sequence(self, connection, sequence_name, schema=None):
481 """Check the existence of a particular sequence in the database.
483 Given a :class:`_engine.Connection` object and a string
484 `sequence_name`, return True if the given sequence exists in
485 the database, False otherwise.
486 """
488 raise NotImplementedError()
490 def _get_server_version_info(self, connection):
491 """Retrieve the server version info from the given connection.
493 This is used by the default implementation to populate the
494 "server_version_info" attribute and is called exactly
495 once upon first connect.
497 """
499 raise NotImplementedError()
501 def _get_default_schema_name(self, connection):
502 """Return the string name of the currently selected schema from
503 the given connection.
505 This is used by the default implementation to populate the
506 "default_schema_name" attribute and is called exactly
507 once upon first connect.
509 """
511 raise NotImplementedError()
513 def do_begin(self, dbapi_connection):
514 """Provide an implementation of ``connection.begin()``, given a
515 DB-API connection.
517 The DBAPI has no dedicated "begin" method and it is expected
518 that transactions are implicit. This hook is provided for those
519 DBAPIs that might need additional help in this area.
521 Note that :meth:`.Dialect.do_begin` is not called unless a
522 :class:`.Transaction` object is in use. The
523 :meth:`.Dialect.do_autocommit`
524 hook is provided for DBAPIs that need some extra commands emitted
525 after a commit in order to enter the next transaction, when the
526 SQLAlchemy :class:`_engine.Connection`
527 is used in its default "autocommit"
528 mode.
530 :param dbapi_connection: a DBAPI connection, typically
531 proxied within a :class:`.ConnectionFairy`.
533 """
535 raise NotImplementedError()
537 def do_rollback(self, dbapi_connection):
538 """Provide an implementation of ``connection.rollback()``, given
539 a DB-API connection.
541 :param dbapi_connection: a DBAPI connection, typically
542 proxied within a :class:`.ConnectionFairy`.
544 """
546 raise NotImplementedError()
548 def do_commit(self, dbapi_connection):
549 """Provide an implementation of ``connection.commit()``, given a
550 DB-API connection.
552 :param dbapi_connection: a DBAPI connection, typically
553 proxied within a :class:`.ConnectionFairy`.
555 """
557 raise NotImplementedError()
559 def do_close(self, dbapi_connection):
560 """Provide an implementation of ``connection.close()``, given a DBAPI
561 connection.
563 This hook is called by the :class:`_pool.Pool`
564 when a connection has been
565 detached from the pool, or is being returned beyond the normal
566 capacity of the pool.
568 """
570 raise NotImplementedError()
572 def create_xid(self):
573 """Create a two-phase transaction ID.
575 This id will be passed to do_begin_twophase(),
576 do_rollback_twophase(), do_commit_twophase(). Its format is
577 unspecified.
578 """
580 raise NotImplementedError()
582 def do_savepoint(self, connection, name):
583 """Create a savepoint with the given name.
585 :param connection: a :class:`_engine.Connection`.
586 :param name: savepoint name.
588 """
590 raise NotImplementedError()
592 def do_rollback_to_savepoint(self, connection, name):
593 """Rollback a connection to the named savepoint.
595 :param connection: a :class:`_engine.Connection`.
596 :param name: savepoint name.
598 """
600 raise NotImplementedError()
602 def do_release_savepoint(self, connection, name):
603 """Release the named savepoint on a connection.
605 :param connection: a :class:`_engine.Connection`.
606 :param name: savepoint name.
607 """
609 raise NotImplementedError()
611 def do_begin_twophase(self, connection, xid):
612 """Begin a two phase transaction on the given connection.
614 :param connection: a :class:`_engine.Connection`.
615 :param xid: xid
617 """
619 raise NotImplementedError()
621 def do_prepare_twophase(self, connection, xid):
622 """Prepare a two phase transaction on the given connection.
624 :param connection: a :class:`_engine.Connection`.
625 :param xid: xid
627 """
629 raise NotImplementedError()
631 def do_rollback_twophase(
632 self, connection, xid, is_prepared=True, recover=False
633 ):
634 """Rollback a two phase transaction on the given connection.
636 :param connection: a :class:`_engine.Connection`.
637 :param xid: xid
638 :param is_prepared: whether or not
639 :meth:`.TwoPhaseTransaction.prepare` was called.
640 :param recover: if the recover flag was passed.
642 """
644 raise NotImplementedError()
646 def do_commit_twophase(
647 self, connection, xid, is_prepared=True, recover=False
648 ):
649 """Commit a two phase transaction on the given connection.
652 :param connection: a :class:`_engine.Connection`.
653 :param xid: xid
654 :param is_prepared: whether or not
655 :meth:`.TwoPhaseTransaction.prepare` was called.
656 :param recover: if the recover flag was passed.
658 """
660 raise NotImplementedError()
662 def do_recover_twophase(self, connection):
663 """Recover list of uncommitted prepared two phase transaction
664 identifiers on the given connection.
666 :param connection: a :class:`_engine.Connection`.
668 """
670 raise NotImplementedError()
672 def do_executemany(self, cursor, statement, parameters, context=None):
673 """Provide an implementation of ``cursor.executemany(statement,
674 parameters)``."""
676 raise NotImplementedError()
678 def do_execute(self, cursor, statement, parameters, context=None):
679 """Provide an implementation of ``cursor.execute(statement,
680 parameters)``."""
682 raise NotImplementedError()
684 def do_execute_no_params(
685 self, cursor, statement, parameters, context=None
686 ):
687 """Provide an implementation of ``cursor.execute(statement)``.
689 The parameter collection should not be sent.
691 """
693 raise NotImplementedError()
695 def is_disconnect(self, e, connection, cursor):
696 """Return True if the given DB-API error indicates an invalid
697 connection"""
699 raise NotImplementedError()
701 def connect(self, *cargs, **cparams):
702 r"""Establish a connection using this dialect's DBAPI.
704 The default implementation of this method is::
706 def connect(self, *cargs, **cparams):
707 return self.dbapi.connect(*cargs, **cparams)
709 The ``*cargs, **cparams`` parameters are generated directly
710 from this dialect's :meth:`.Dialect.create_connect_args` method.
712 This method may be used for dialects that need to perform programmatic
713 per-connection steps when a new connection is procured from the
714 DBAPI.
717 :param \*cargs: positional parameters returned from the
718 :meth:`.Dialect.create_connect_args` method
720 :param \*\*cparams: keyword parameters returned from the
721 :meth:`.Dialect.create_connect_args` method.
723 :return: a DBAPI connection, typically from the :pep:`249` module
724 level ``.connect()`` function.
726 .. seealso::
728 :meth:`.Dialect.create_connect_args`
730 :meth:`.Dialect.on_connect`
732 """
734 def on_connect(self):
735 """return a callable which sets up a newly created DBAPI connection.
737 The callable should accept a single argument "conn" which is the
738 DBAPI connection itself. The inner callable has no
739 return value.
741 E.g.::
743 class MyDialect(default.DefaultDialect):
744 # ...
746 def on_connect(self):
747 def do_on_connect(connection):
748 connection.execute("SET SPECIAL FLAGS etc")
750 return do_on_connect
752 This is used to set dialect-wide per-connection options such as
753 isolation modes, Unicode modes, etc.
755 The "do_on_connect" callable is invoked by using the
756 :meth:`_events.PoolEvents.first_connect` and
757 :meth:`_events.PoolEvents.connect` event
758 hooks, then unwrapping the DBAPI connection and passing it into the
759 callable. The reason it is invoked for both events is so that any
760 dialect-level initialization that occurs upon first connection, which
761 also makes use of the :meth:`_events.PoolEvents.first_connect` method,
762 will
763 proceed after this hook has been called. This currently means the
764 hook is in fact called twice for the very first connection in which a
765 dialect creates; and once per connection afterwards.
767 If None is returned, no event listener is generated.
769 :return: a callable that accepts a single DBAPI connection as an
770 argument, or None.
772 .. seealso::
774 :meth:`.Dialect.connect` - allows the DBAPI ``connect()`` sequence
775 itself to be controlled.
777 """
778 return None
780 def reset_isolation_level(self, dbapi_conn):
781 """Given a DBAPI connection, revert its isolation to the default.
783 Note that this is a dialect-level method which is used as part
784 of the implementation of the :class:`_engine.Connection` and
785 :class:`_engine.Engine`
786 isolation level facilities; these APIs should be preferred for
787 most typical use cases.
789 .. seealso::
791 :meth:`_engine.Connection.get_isolation_level`
792 - view current level
794 :attr:`_engine.Connection.default_isolation_level`
795 - view default level
797 :paramref:`.Connection.execution_options.isolation_level` -
798 set per :class:`_engine.Connection` isolation level
800 :paramref:`_sa.create_engine.isolation_level` -
801 set per :class:`_engine.Engine` isolation level
803 """
805 raise NotImplementedError()
807 def set_isolation_level(self, dbapi_conn, level):
808 """Given a DBAPI connection, set its isolation level.
810 Note that this is a dialect-level method which is used as part
811 of the implementation of the :class:`_engine.Connection` and
812 :class:`_engine.Engine`
813 isolation level facilities; these APIs should be preferred for
814 most typical use cases.
816 .. seealso::
818 :meth:`_engine.Connection.get_isolation_level`
819 - view current level
821 :attr:`_engine.Connection.default_isolation_level`
822 - view default level
824 :paramref:`.Connection.execution_options.isolation_level` -
825 set per :class:`_engine.Connection` isolation level
827 :paramref:`_sa.create_engine.isolation_level` -
828 set per :class:`_engine.Engine` isolation level
830 """
832 raise NotImplementedError()
834 def get_isolation_level(self, dbapi_conn):
835 """Given a DBAPI connection, return its isolation level.
837 When working with a :class:`_engine.Connection` object,
838 the corresponding
839 DBAPI connection may be procured using the
840 :attr:`_engine.Connection.connection` accessor.
842 Note that this is a dialect-level method which is used as part
843 of the implementation of the :class:`_engine.Connection` and
844 :class:`_engine.Engine` isolation level facilities;
845 these APIs should be preferred for most typical use cases.
848 .. seealso::
850 :meth:`_engine.Connection.get_isolation_level`
851 - view current level
853 :attr:`_engine.Connection.default_isolation_level`
854 - view default level
856 :paramref:`.Connection.execution_options.isolation_level` -
857 set per :class:`_engine.Connection` isolation level
859 :paramref:`_sa.create_engine.isolation_level` -
860 set per :class:`_engine.Engine` isolation level
863 """
865 raise NotImplementedError()
867 @classmethod
868 def get_dialect_cls(cls, url):
869 """Given a URL, return the :class:`.Dialect` that will be used.
871 This is a hook that allows an external plugin to provide functionality
872 around an existing dialect, by allowing the plugin to be loaded
873 from the url based on an entrypoint, and then the plugin returns
874 the actual dialect to be used.
876 By default this just returns the cls.
878 .. versionadded:: 1.0.3
880 """
881 return cls
883 @classmethod
884 def load_provisioning(cls):
885 """set up the provision.py module for this dialect.
887 For dialects that include a provision.py module that sets up
888 provisioning followers, this method should initiate that process.
890 A typical implementation would be::
892 @classmethod
893 def load_provisioning(cls):
894 __import__("mydialect.provision")
896 The default method assumes a module named ``provision.py`` inside
897 the owning package of the current dialect, based on the ``__module__``
898 attribute::
900 @classmethod
901 def load_provisioning(cls):
902 package = ".".join(cls.__module__.split(".")[0:-1])
903 try:
904 __import__(package + ".provision")
905 except ImportError:
906 pass
908 .. versionadded:: 1.3.14
910 """
912 @classmethod
913 def engine_created(cls, engine):
914 """A convenience hook called before returning the final
915 :class:`_engine.Engine`.
917 If the dialect returned a different class from the
918 :meth:`.get_dialect_cls`
919 method, then the hook is called on both classes, first on
920 the dialect class returned by the :meth:`.get_dialect_cls` method and
921 then on the class on which the method was called.
923 The hook should be used by dialects and/or wrappers to apply special
924 events to the engine or its components. In particular, it allows
925 a dialect-wrapping class to apply dialect-level events.
927 .. versionadded:: 1.0.3
929 """
930 pass
933class CreateEnginePlugin(object):
934 """A set of hooks intended to augment the construction of an
935 :class:`_engine.Engine` object based on entrypoint names in a URL.
937 The purpose of :class:`.CreateEnginePlugin` is to allow third-party
938 systems to apply engine, pool and dialect level event listeners without
939 the need for the target application to be modified; instead, the plugin
940 names can be added to the database URL. Target applications for
941 :class:`.CreateEnginePlugin` include:
943 * connection and SQL performance tools, e.g. which use events to track
944 number of checkouts and/or time spent with statements
946 * connectivity plugins such as proxies
948 Plugins are registered using entry points in a similar way as that
949 of dialects::
951 entry_points={
952 'sqlalchemy.plugins': [
953 'myplugin = myapp.plugins:MyPlugin'
954 ]
956 A plugin that uses the above names would be invoked from a database
957 URL as in::
959 from sqlalchemy import create_engine
961 engine = create_engine(
962 "mysql+pymysql://scott:tiger@localhost/test?plugin=myplugin")
964 Alternatively, the :paramref:`.create_engine.plugins" argument may be
965 passed as a list to :func:`_sa.create_engine`::
967 engine = create_engine(
968 "mysql+pymysql://scott:tiger@localhost/test",
969 plugins=["myplugin"])
971 .. versionadded:: 1.2.3 plugin names can also be specified
972 to :func:`_sa.create_engine` as a list
974 The ``plugin`` argument supports multiple instances, so that a URL
975 may specify multiple plugins; they are loaded in the order stated
976 in the URL::
978 engine = create_engine(
979 "mysql+pymysql://scott:tiger@localhost/"
980 "test?plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three")
982 A plugin can receive additional arguments from the URL string as
983 well as from the keyword arguments passed to :func:`_sa.create_engine`.
984 The :class:`.URL` object and the keyword dictionary are passed to the
985 constructor so that these arguments can be extracted from the url's
986 :attr:`.URL.query` collection as well as from the dictionary::
988 class MyPlugin(CreateEnginePlugin):
989 def __init__(self, url, kwargs):
990 self.my_argument_one = url.query.pop('my_argument_one')
991 self.my_argument_two = url.query.pop('my_argument_two')
992 self.my_argument_three = kwargs.pop('my_argument_three', None)
994 Arguments like those illustrated above would be consumed from the
995 following::
997 from sqlalchemy import create_engine
999 engine = create_engine(
1000 "mysql+pymysql://scott:tiger@localhost/"
1001 "test?plugin=myplugin&my_argument_one=foo&my_argument_two=bar",
1002 my_argument_three='bat')
1004 The URL and dictionary are used for subsequent setup of the engine
1005 as they are, so the plugin can modify their arguments in-place.
1006 Arguments that are only understood by the plugin should be popped
1007 or otherwise removed so that they aren't interpreted as erroneous
1008 arguments afterwards.
1010 When the engine creation process completes and produces the
1011 :class:`_engine.Engine` object, it is again passed to the plugin via the
1012 :meth:`.CreateEnginePlugin.engine_created` hook. In this hook, additional
1013 changes can be made to the engine, most typically involving setup of
1014 events (e.g. those defined in :ref:`core_event_toplevel`).
1016 .. versionadded:: 1.1
1018 """
1020 def __init__(self, url, kwargs):
1021 """Construct a new :class:`.CreateEnginePlugin`.
1023 The plugin object is instantiated individually for each call
1024 to :func:`_sa.create_engine`. A single :class:`_engine.
1025 Engine` will be
1026 passed to the :meth:`.CreateEnginePlugin.engine_created` method
1027 corresponding to this URL.
1029 :param url: the :class:`.URL` object. The plugin should inspect
1030 what it needs here as well as remove its custom arguments from the
1031 :attr:`.URL.query` collection. The URL can be modified in-place
1032 in any other way as well.
1033 :param kwargs: The keyword arguments passed to :func`.create_engine`.
1034 The plugin can read and modify this dictionary in-place, to affect
1035 the ultimate arguments used to create the engine. It should
1036 remove its custom arguments from the dictionary as well.
1038 """
1039 self.url = url
1041 def handle_dialect_kwargs(self, dialect_cls, dialect_args):
1042 """parse and modify dialect kwargs"""
1044 def handle_pool_kwargs(self, pool_cls, pool_args):
1045 """parse and modify pool kwargs"""
1047 def engine_created(self, engine):
1048 """Receive the :class:`_engine.Engine`
1049 object when it is fully constructed.
1051 The plugin may make additional changes to the engine, such as
1052 registering engine or connection pool events.
1054 """
1057class ExecutionContext(object):
1058 """A messenger object for a Dialect that corresponds to a single
1059 execution.
1061 ExecutionContext should have these data members:
1063 connection
1064 Connection object which can be freely used by default value
1065 generators to execute SQL. This Connection should reference the
1066 same underlying connection/transactional resources of
1067 root_connection.
1069 root_connection
1070 Connection object which is the source of this ExecutionContext. This
1071 Connection may have close_with_result=True set, in which case it can
1072 only be used once.
1074 dialect
1075 dialect which created this ExecutionContext.
1077 cursor
1078 DB-API cursor procured from the connection,
1080 compiled
1081 if passed to constructor, sqlalchemy.engine.base.Compiled object
1082 being executed,
1084 statement
1085 string version of the statement to be executed. Is either
1086 passed to the constructor, or must be created from the
1087 sql.Compiled object by the time pre_exec() has completed.
1089 parameters
1090 bind parameters passed to the execute() method. For compiled
1091 statements, this is a dictionary or list of dictionaries. For
1092 textual statements, it should be in a format suitable for the
1093 dialect's paramstyle (i.e. dict or list of dicts for non
1094 positional, list or list of lists/tuples for positional).
1096 isinsert
1097 True if the statement is an INSERT.
1099 isupdate
1100 True if the statement is an UPDATE.
1102 should_autocommit
1103 True if the statement is a "committable" statement.
1105 prefetch_cols
1106 a list of Column objects for which a client-side default
1107 was fired off. Applies to inserts and updates.
1109 postfetch_cols
1110 a list of Column objects for which a server-side default or
1111 inline SQL expression value was fired off. Applies to inserts
1112 and updates.
1113 """
1115 exception = None
1116 """A DBAPI-level exception that was caught when this ExecutionContext
1117 attempted to execute a statement.
1119 This attribute is meaningful only within the
1120 :meth:`_events.ConnectionEvents.dbapi_error` event.
1122 .. versionadded:: 0.9.7
1124 .. seealso::
1126 :attr:`.ExecutionContext.is_disconnect`
1128 :meth:`_events.ConnectionEvents.dbapi_error`
1130 """
1132 is_disconnect = None
1133 """Boolean flag set to True or False when a DBAPI-level exception
1134 is caught when this ExecutionContext attempted to execute a statement.
1136 This attribute is meaningful only within the
1137 :meth:`_events.ConnectionEvents.dbapi_error` event.
1139 .. versionadded:: 0.9.7
1141 .. seealso::
1143 :attr:`.ExecutionContext.exception`
1145 :meth:`_events.ConnectionEvents.dbapi_error`
1147 """
1149 def create_cursor(self):
1150 """Return a new cursor generated from this ExecutionContext's
1151 connection.
1153 Some dialects may wish to change the behavior of
1154 connection.cursor(), such as postgresql which may return a PG
1155 "server side" cursor.
1156 """
1158 raise NotImplementedError()
1160 def pre_exec(self):
1161 """Called before an execution of a compiled statement.
1163 If a compiled statement was passed to this ExecutionContext,
1164 the `statement` and `parameters` datamembers must be
1165 initialized after this statement is complete.
1166 """
1168 raise NotImplementedError()
1170 def post_exec(self):
1171 """Called after the execution of a compiled statement.
1173 If a compiled statement was passed to this ExecutionContext,
1174 the `last_insert_ids`, `last_inserted_params`, etc.
1175 datamembers should be available after this method completes.
1176 """
1178 raise NotImplementedError()
1180 def result(self):
1181 """Return a result object corresponding to this ExecutionContext.
1183 Returns a ResultProxy.
1184 """
1186 raise NotImplementedError()
1188 def handle_dbapi_exception(self, e):
1189 """Receive a DBAPI exception which occurred upon execute, result
1190 fetch, etc."""
1192 raise NotImplementedError()
1194 def should_autocommit_text(self, statement):
1195 """Parse the given textual statement and return True if it refers to
1196 a "committable" statement"""
1198 raise NotImplementedError()
1200 def lastrow_has_defaults(self):
1201 """Return True if the last INSERT or UPDATE row contained
1202 inlined or database-side defaults.
1203 """
1205 raise NotImplementedError()
1207 def get_rowcount(self):
1208 """Return the DBAPI ``cursor.rowcount`` value, or in some
1209 cases an interpreted value.
1211 See :attr:`_engine.ResultProxy.rowcount` for details on this.
1213 """
1215 raise NotImplementedError()
1218class Connectable(object):
1219 """Interface for an object which supports execution of SQL constructs.
1221 The two implementations of :class:`.Connectable` are
1222 :class:`_engine.Connection` and :class:`_engine.Engine`.
1224 Connectable must also implement the 'dialect' member which references a
1225 :class:`.Dialect` instance.
1227 """
1229 def connect(self, **kwargs):
1230 """Return a :class:`_engine.Connection` object.
1232 Depending on context, this may be ``self`` if this object
1233 is already an instance of :class:`_engine.Connection`, or a newly
1234 procured :class:`_engine.Connection` if this object is an instance
1235 of :class:`_engine.Engine`.
1237 """
1239 engine = None
1240 """The :class:`_engine.Engine` instance referred to by this
1241 :class:`.Connectable`.
1243 May be ``self`` if this is already an :class:`_engine.Engine`.
1245 """
1247 @util.deprecated(
1248 "1.3",
1249 "The :meth:`_engine.Engine.contextual_connect` and "
1250 ":meth:`_engine.Connection.contextual_connect` methods are "
1251 "deprecated. This "
1252 "method is an artifact of the threadlocal engine strategy which is "
1253 "also to be deprecated. For explicit connections from an "
1254 ":class:`_engine.Engine`, use the :meth:`_engine.Engine.connect` "
1255 "method.",
1256 )
1257 def contextual_connect(self, *arg, **kw):
1258 """Return a :class:`_engine.Connection`
1259 object which may be part of an ongoing
1260 context.
1262 Depending on context, this may be ``self`` if this object
1263 is already an instance of :class:`_engine.Connection`, or a newly
1264 procured :class:`_engine.Connection` if this object is an instance
1265 of :class:`_engine.Engine`.
1267 """
1269 return self._contextual_connect(*arg, **kw)
1271 def _contextual_connect(self):
1272 raise NotImplementedError()
1274 @util.deprecated(
1275 "0.7",
1276 "The :meth:`.Connectable.create` method is deprecated and will be "
1277 "removed in a future release. Please use the ``.create()`` method "
1278 "on specific schema objects to emit DDL sequences, including "
1279 ":meth:`_schema.Table.create`, :meth:`.Index.create`, and "
1280 ":meth:`_schema.MetaData.create_all`.",
1281 )
1282 def create(self, entity, **kwargs):
1283 """Emit CREATE statements for the given schema entity.
1284 """
1286 raise NotImplementedError()
1288 @util.deprecated(
1289 "0.7",
1290 "The :meth:`.Connectable.drop` method is deprecated and will be "
1291 "removed in a future release. Please use the ``.drop()`` method "
1292 "on specific schema objects to emit DDL sequences, including "
1293 ":meth:`_schema.Table.drop`, :meth:`.Index.drop`, and "
1294 ":meth:`_schema.MetaData.drop_all`.",
1295 )
1296 def drop(self, entity, **kwargs):
1297 """Emit DROP statements for the given schema entity.
1298 """
1300 raise NotImplementedError()
1302 def execute(self, object_, *multiparams, **params):
1303 """Executes the given construct and returns a """
1304 """:class:`_engine.ResultProxy`."""
1305 raise NotImplementedError()
1307 def scalar(self, object_, *multiparams, **params):
1308 """Executes and returns the first column of the first row.
1310 The underlying cursor is closed after execution.
1311 """
1312 raise NotImplementedError()
1314 def _run_visitor(self, visitorcallable, element, **kwargs):
1315 raise NotImplementedError()
1317 def _execute_clauseelement(self, elem, multiparams=None, params=None):
1318 raise NotImplementedError()
1321class ExceptionContext(object):
1322 """Encapsulate information about an error condition in progress.
1324 This object exists solely to be passed to the
1325 :meth:`_events.ConnectionEvents.handle_error` event,
1326 supporting an interface that
1327 can be extended without backwards-incompatibility.
1329 .. versionadded:: 0.9.7
1331 """
1333 connection = None
1334 """The :class:`_engine.Connection` in use during the exception.
1336 This member is present, except in the case of a failure when
1337 first connecting.
1339 .. seealso::
1341 :attr:`.ExceptionContext.engine`
1344 """
1346 engine = None
1347 """The :class:`_engine.Engine` in use during the exception.
1349 This member should always be present, even in the case of a failure
1350 when first connecting.
1352 .. versionadded:: 1.0.0
1354 """
1356 cursor = None
1357 """The DBAPI cursor object.
1359 May be None.
1361 """
1363 statement = None
1364 """String SQL statement that was emitted directly to the DBAPI.
1366 May be None.
1368 """
1370 parameters = None
1371 """Parameter collection that was emitted directly to the DBAPI.
1373 May be None.
1375 """
1377 original_exception = None
1378 """The exception object which was caught.
1380 This member is always present.
1382 """
1384 sqlalchemy_exception = None
1385 """The :class:`sqlalchemy.exc.StatementError` which wraps the original,
1386 and will be raised if exception handling is not circumvented by the event.
1388 May be None, as not all exception types are wrapped by SQLAlchemy.
1389 For DBAPI-level exceptions that subclass the dbapi's Error class, this
1390 field will always be present.
1392 """
1394 chained_exception = None
1395 """The exception that was returned by the previous handler in the
1396 exception chain, if any.
1398 If present, this exception will be the one ultimately raised by
1399 SQLAlchemy unless a subsequent handler replaces it.
1401 May be None.
1403 """
1405 execution_context = None
1406 """The :class:`.ExecutionContext` corresponding to the execution
1407 operation in progress.
1409 This is present for statement execution operations, but not for
1410 operations such as transaction begin/end. It also is not present when
1411 the exception was raised before the :class:`.ExecutionContext`
1412 could be constructed.
1414 Note that the :attr:`.ExceptionContext.statement` and
1415 :attr:`.ExceptionContext.parameters` members may represent a
1416 different value than that of the :class:`.ExecutionContext`,
1417 potentially in the case where a
1418 :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar
1419 modified the statement/parameters to be sent.
1421 May be None.
1423 """
1425 is_disconnect = None
1426 """Represent whether the exception as occurred represents a "disconnect"
1427 condition.
1429 This flag will always be True or False within the scope of the
1430 :meth:`_events.ConnectionEvents.handle_error` handler.
1432 SQLAlchemy will defer to this flag in order to determine whether or not
1433 the connection should be invalidated subsequently. That is, by
1434 assigning to this flag, a "disconnect" event which then results in
1435 a connection and pool invalidation can be invoked or prevented by
1436 changing this flag.
1438 """
1440 invalidate_pool_on_disconnect = True
1441 """Represent whether all connections in the pool should be invalidated
1442 when a "disconnect" condition is in effect.
1444 Setting this flag to False within the scope of the
1445 :meth:`_events.ConnectionEvents.handle_error`
1446 event will have the effect such
1447 that the full collection of connections in the pool will not be
1448 invalidated during a disconnect; only the current connection that is the
1449 subject of the error will actually be invalidated.
1451 The purpose of this flag is for custom disconnect-handling schemes where
1452 the invalidation of other connections in the pool is to be performed
1453 based on other conditions, or even on a per-connection basis.
1455 .. versionadded:: 1.0.3
1457 """