summaryrefslogtreecommitdiff
path: root/doc/build/faq/connections.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/build/faq/connections.rst')
-rw-r--r--doc/build/faq/connections.rst95
1 files changed, 87 insertions, 8 deletions
diff --git a/doc/build/faq/connections.rst b/doc/build/faq/connections.rst
index 79e8804c1..1bee24c32 100644
--- a/doc/build/faq/connections.rst
+++ b/doc/build/faq/connections.rst
@@ -406,28 +406,107 @@ current SQLAlchemy versions.
:ref:`pysqlite_threading_pooling` - info on PySQLite's behavior.
+.. _faq_dbapi_connection:
+
How do I get at the raw DBAPI connection when using an Engine?
--------------------------------------------------------------
With a regular SA engine-level Connection, you can get at a pool-proxied
version of the DBAPI connection via the :attr:`_engine.Connection.connection` attribute on
:class:`_engine.Connection`, and for the really-real DBAPI connection you can call the
-:attr:`.ConnectionFairy.connection` attribute on that - but there should never be any need to access
-the non-pool-proxied DBAPI connection, as all methods are proxied through::
+:attr:`._ConnectionFairy.dbapi_connection` attribute on that. On regular sync drivers
+there is usually no need to access the non-pool-proxied DBAPI connection,
+as all methods are proxied through::
engine = create_engine(...)
conn = engine.connect()
- conn.connection.<do DBAPI things>
- cursor_obj = conn.connection.cursor(<DBAPI specific arguments..>)
+
+ # pep-249 style ConnectionFairy connection pool proxy object
+ connection_fairy = conn.connection
+
+ # typically to run statements one would get a cursor() from this
+ # object
+ cursor_obj = connection_fairy.cursor()
+ # ... work with cursor_obj
+
+ # to bypass "connection_fairy", such as to set attributes on the
+ # unproxied pep-249 DBAPI connection, use .dbapi_connection
+ raw_dbapi_connection = connection_fairy.dbapi_connection
+
+ # the same thing is available as .driver_connection (more on this
+ # in the next section)
+ also_raw_dbapi_connection = connection_fairy.driver_connection
+
+.. versionchanged:: 1.4.24 Added the
+ :attr:`._ConnectionFairy.dbapi_connection` attribute,
+ which supersedes the previous
+ :attr:`._ConnectionFairy.connection` attribute which still remains
+ available; this attribute always provides a pep-249 synchronous style
+ connection object. The :attr:`._ConnectionFairy.driver_connection`
+ attribute is also added which will always refer to the real driver-level
+ connection regardless of what API it presents.
+
+Accessing the underlying connnection for an asyncio driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When an asyncio driver is in use, there are two changes to the above
+scheme. The first is that when using an :class:`_asyncio.AsyncConnection`,
+the :class:`._ConnectionFairy` must be accessed using the awaitable method
+:meth:`_asyncio.AsyncConnection.get_raw_connection`. The
+returned :class:`._ConnectionFairy` in this case retains a sync-style
+pep-249 usage pattern, and the :attr:`._ConnectionFairy.dbapi_connection`
+attribute refers to a
+a SQLAlchemy-adapted connection object which adapts the asyncio
+connection to a sync style pep-249 API, in other words there are *two* levels
+of proxying going on when using an asyncio driver. The actual asyncio connection
+is available from the :class:`._ConnectionFairy.driver_connection` attribute.
+To restate the previous example in terms of asyncio looks like::
+
+ async def main():
+ engine = create_async_engine(...)
+ conn = await engine.connect()
+
+ # pep-249 style ConnectionFairy connection pool proxy object
+ # presents a sync interface
+ connection_fairy = await conn.get_raw_connection()
+
+ # beneath that proxy is a second proxy which adapts the
+ # asyncio driver into a pep-249 connection object, accessible
+ # via .dbapi_connection as is the same with a sync API
+ sqla_sync_conn = connection_fairy.dbapi_connection
+
+ # the really-real innermost driver connection is available
+ # from the .driver_connection attribute
+ raw_asyncio_connection = connection_fairy.driver_connection
+
+ # work with raw asyncio connection
+ result = await raw_asyncio_connection.execute(...)
+
+.. versionchanged:: 1.4.24 Added the
+ :attr:`._ConnectionFairy.dbapi_connection`
+ and :attr:`._ConnectionFairy.driver_connection` attributes to allow access
+ to pep-249 connections, pep-249 adaption layers, and underlying driver
+ connections using a consistent interface.
+
+When using asyncio drivers, the above "DBAPI" connection is actually a
+SQLAlchemy-adapted form of connection which presents a synchronous-style
+pep-249 style API. To access the actual
+asyncio driver connection, which will present the original asyncio API
+of the driver in use, this can be accessed via the
+:attr:`._ConnectionFairy.driver_connection` attribute of
+:class:`._ConnectionFairy`.
+For a standard pep-249 driver, :attr:`._ConnectionFairy.dbapi_connection`
+and :attr:`._ConnectionFairy.driver_connection` are synonymous.
You must ensure that you revert any isolation level settings or other
operation-specific settings on the connection back to normal before returning
it to the pool.
-As an alternative to reverting settings, you can call the :meth:`_engine.Connection.detach` method on
-either :class:`_engine.Connection` or the proxied connection, which will de-associate
-the connection from the pool such that it will be closed and discarded
-when :meth:`_engine.Connection.close` is called::
+As an alternative to reverting settings, you can call the
+:meth:`_engine.Connection.detach` method on either :class:`_engine.Connection`
+or the proxied connection, which will de-associate the connection from the pool
+such that it will be closed and discarded when :meth:`_engine.Connection.close`
+is called::
conn = engine.connect()
conn.detach() # detaches the DBAPI connection from the connection pool