Underneath the public-facing API of `Engine`, several components are provided by database implementations to provide the full behavior, including:
* [Dialect](boldrel:docstrings_sqlalchemy.engine_Dialect) - this object is provided by database implementations to describe the behavior of a particular database. It acts as a repository for metadata about a database's characteristics, and provides factory methods for other objects that deal with generating SQL strings and objects that handle some of the details of statement execution.
-* [ConnectionProvider](boldrel:docstrings_sqlalchemy.engine_ConnectionProvider) - this object knows how to return a DBAPI connection object. It typically talks to a connection pool which maintains one or more connections in memory for quick re-use.
+* [Pool](boldrel:docstrings_sqlalchemy.pool_Pool) - provides DBAPI connections from a managed pool of connections. All `Engine` objects use a connection pool, which can be provided by a variety of different backend strategies. The most common is [QueuePool](rel:docstrings_sqlalchemy.pool_QueuePool).
* [ExecutionContext](boldrel:docstrings_sqlalchemy.engine_ExecutionContext) - this object is created for each execution of a single SQL statement, and tracks information about its execution such as primary keys inserted, the total count of rows affected, etc. It also may implement any special logic that various DBAPI implementations may require before or after a statement execution.
-* [Compiled](boldrel:docstrings_sqlalchemy.sql_Compiled) - represents a "compiled" SQL expression object. Includes a `compile()` method which receives SQL expression objects and assembles them into strings that are suitable for direct execution. Also collects default bind parameters into a datastructure that will be converted at execution time into a dictionary or list, depending on the dialect's paramstyle.
+* [Compiled](boldrel:docstrings_sqlalchemy.engine_Compiled) - represents a "compiled" SQL expression object. Includes a `compile()` method which receives SQL expression objects and assembles them into strings that are suitable for direct execution. Also collects default bind parameters into a datastructure that will be converted at execution time into a dictionary or list, depending on the dialect's paramstyle.
### Supported Databases {@name=supported}
import re
from sqlalchemy import schema, types, ansisql, engine, sql, pool, orm, exceptions, databases
-import sqlalchemy.ext.proxy as proxy
import sqlalchemy.ext.sessioncontext as sessioncontext
import sqlalchemy.mods.threadlocal as threadlocal
import sqlalchemy.ext.selectresults as selectresults
make_doc(obj=sessioncontext),
make_doc(obj=threadlocal),
make_doc(obj=selectresults),
- make_doc(obj=proxy),
make_doc(obj=orderinglist, classes=[orderinglist.OrderingList]),
make_doc(obj=associationproxy, classes=[associationproxy.AssociationProxy]),
] + [make_doc(getattr(__import__('sqlalchemy.databases.%s' % m).databases, m)) for m in databases.__all__]
import StringIO, sys, re
-class ConnectionProvider(object):
- """Define an interface that returns raw Connection objects (or compatible)."""
-
- def get_connection(self):
- """Return a Connection or compatible object from a DBAPI which also contains a close() method.
-
- It is not defined what context this connection belongs to. It
- may be newly connected, returned from a pool, part of some
- other kind of context such as thread-local, or can be a fixed
- member of this object.
- """
-
- raise NotImplementedError()
-
- def dispose(self):
- """Release all resources corresponding to this ConnectionProvider.
-
- This includes any underlying connection pools.
- """
-
- raise NotImplementedError()
-
-
class Dialect(sql.AbstractDialect):
"""Define the behavior of a specific database/DBAPI.
except Exception, e:
if self.dialect.is_disconnect(e):
self.__connection.invalidate(e=e)
- self.engine.connection_provider.dispose()
+ self.engine.dispose()
self._autorollback()
if self.__close_with_result:
self.close()
except Exception, e:
if self.dialect.is_disconnect(e):
self.__connection.invalidate(e=e)
- self.engine.connection_provider.dispose()
+ self.engine.dispose()
self._autorollback()
if self.__close_with_result:
self.close()
class Engine(Connectable):
"""
- Connects a ConnectionProvider, a Dialect and a CompilerFactory together to
+ Connects a Pool, a Dialect and a CompilerFactory together to
provide a default implementation of SchemaEngine.
"""
- def __init__(self, connection_provider, dialect, echo=None):
- self.connection_provider = connection_provider
+ def __init__(self, pool, dialect, url, echo=None):
+ self.pool = pool
+ self.url = url
self._dialect=dialect
self.echo = echo
self.logger = logging.instance_logger(self)
engine = property(lambda s:s)
dialect = property(lambda s:s._dialect, doc="the [sqlalchemy.engine#Dialect] in use by this engine.")
echo = logging.echo_property()
- url = property(lambda s:s.connection_provider.url, doc="The [sqlalchemy.engine.url#URL] object representing this ``Engine`` object's datasource.")
def dispose(self):
- self.connection_provider.dispose()
+ self.pool.dispose()
+ self.pool = self.pool.recreate()
def create(self, entity, connection=None, **kwargs):
"""Create a table or index within this engine's database connection given a schema.Table object."""
def raw_connection(self):
"""Return a DBAPI connection."""
- return self.connection_provider.get_connection()
+ return self.pool.connect()
def log(self, msg):
"""Log a message using this SQLEngine's logger stream."""
"""Provide default implementations of the engine interfaces"""
-class PoolConnectionProvider(base.ConnectionProvider):
- def __init__(self, url, pool):
- self.url = url
- self._pool = pool
-
- def get_connection(self):
- return self._pool.connect()
-
- def dispose(self):
- self._pool.dispose()
- self._pool = self._pool.recreate()
class DefaultDialect(base.Dialect):
"""Default implementation of Dialect"""
else:
pool = pool
- provider = self.get_pool_provider(u, pool)
-
# create engine.
engineclass = self.get_engine_cls()
engine_args = {}
if len(kwargs):
raise TypeError("Invalid argument(s) %s sent to create_engine(), using configuration %s/%s/%s. Please check that the keyword arguments are appropriate for this combination of components." % (','.join(["'%s'" % k for k in kwargs]), dialect.__class__.__name__, pool.__class__.__name__, engineclass.__name__))
- return engineclass(provider, dialect, **engine_args)
+ return engineclass(pool, dialect, u, **engine_args)
def pool_threadlocal(self):
raise NotImplementedError()
- def get_pool_provider(self, url, pool):
- raise NotImplementedError()
-
def get_engine_cls(self):
raise NotImplementedError()
def pool_threadlocal(self):
return False
- def get_pool_provider(self, url, pool):
- return default.PoolConnectionProvider(url, pool)
-
def get_engine_cls(self):
return base.Engine
def pool_threadlocal(self):
return True
- def get_pool_provider(self, url, pool):
- return threadlocal.TLocalConnectionProvider(url, pool)
-
def get_engine_cls(self):
return threadlocal.TLEngine
"""
def __init__(self, *args, **kwargs):
- """The TLEngine relies upon the ConnectionProvider having
+ """The TLEngine relies upon the Pool having
"threadlocal" behavior, so that once a connection is checked out
for the current thread, you get that same connection
repeatedly.
def raw_connection(self):
"""Return a DBAPI connection."""
- return self.connection_provider.get_connection()
+ return self.pool.connect()
def connect(self, **kwargs):
"""Return a Connection that is not thread-locally scoped.
ComposedSQLEngine.
"""
- return base.Connection(self, self.connection_provider.unique_connection())
+ return base.Connection(self, self.pool.unique_connection())
def _session(self):
if not hasattr(self.context, 'session'):
def rollback(self):
self.session.rollback()
-class TLocalConnectionProvider(default.PoolConnectionProvider):
- def unique_connection(self):
- return self._pool.unique_connection()
def testrecycle(self):
dbapi = MockDBAPI(foober=12, lala=18, hoho={'this':'dict'}, fooz='somevalue')
e = create_engine('postgres://', pool_recycle=472, module=dbapi)
- assert e.connection_provider._pool._recycle == 472
+ assert e.pool._recycle == 472
def testbadargs(self):
# good arg, use MockDBAPI to prevent oracle import errors
def testpoolargs(self):
"""test that connection pool args make it thru"""
e = create_engine('postgres://', creator=None, pool_recycle=-1, echo_pool=None, auto_close_cursors=False, disallow_open_cursors=True, module=MockDBAPI())
- assert e.connection_provider._pool.auto_close_cursors is False
- assert e.connection_provider._pool.disallow_open_cursors is True
+ assert e.pool.auto_close_cursors is False
+ assert e.pool.disallow_open_cursors is True
# these args work for QueuePool
e = create_engine('postgres://', max_overflow=8, pool_timeout=60, poolclass=pool.QueuePool, module=MockDBAPI())
# monkeypatch disconnect checker
db.dialect.is_disconnect = lambda e: isinstance(e, MockDisconnect)
- pid = id(db.connection_provider._pool)
+ pid = id(db.pool)
# make a connection
conn = db.connect()
# close shouldnt break
conn.close()
- assert id(db.connection_provider._pool) != pid
+ assert id(db.pool) != pid
# ensure all connections closed (pool was recycled)
assert len(dbapi.connections) == 0