diff options
| author | Brad Allen <bradallen137@gmail.com> | 2010-03-15 11:42:35 -0600 |
|---|---|---|
| committer | Brad Allen <bradallen137@gmail.com> | 2010-03-15 11:42:35 -0600 |
| commit | 00ac90accb8d29cd665a9c14089c51a32afb3bd8 (patch) | |
| tree | 0c3ae3d78d0f2b929e49e071ef8ce426e20eaf23 /lib/sqlalchemy/engine | |
| parent | 96209a12486df72ab0b2285441de8505489e26b3 (diff) | |
| parent | 5dcc32fd5a81c41b50bc35573d190a60a344c3c6 (diff) | |
| download | sqlalchemy-00ac90accb8d29cd665a9c14089c51a32afb3bd8.tar.gz | |
merged mainline default branch
Diffstat (limited to 'lib/sqlalchemy/engine')
| -rw-r--r-- | lib/sqlalchemy/engine/__init__.py | 12 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/base.py | 39 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/default.py | 56 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/strategies.py | 15 |
4 files changed, 100 insertions, 22 deletions
diff --git a/lib/sqlalchemy/engine/__init__.py b/lib/sqlalchemy/engine/__init__.py index 8911485cb..9a53545df 100644 --- a/lib/sqlalchemy/engine/__init__.py +++ b/lib/sqlalchemy/engine/__init__.py @@ -118,7 +118,7 @@ def create_engine(*args, **kwargs): Pool. Specific dialects also accept keyword arguments that are unique to that dialect. Here, we describe the parameters that are common to most ``create_engine()`` usage. - + :param assert_unicode: Deprecated. A warning is raised in all cases when a non-Unicode object is passed when SQLAlchemy would coerce into an encoding (note: but **not** when the DBAPI handles unicode objects natively). @@ -144,6 +144,11 @@ def create_engine(*args, **kwargs): connections. Usage of this function causes connection parameters specified in the URL argument to be bypassed. + :param logging_name: String identifier which will be used within + the "name" field of logging records generated within the + "sqlalchemy.engine" logger. Defaults to a hexstring of the + object's id. + :param echo=False: if True, the Engine will log all statements as well as a repr() of their parameter lists to the engines logger, which defaults to sys.stdout. The ``echo`` attribute of @@ -153,6 +158,11 @@ def create_engine(*args, **kwargs): controls a Python logger; see :ref:`dbengine_logging` for information on how to configure logging directly. + :param pool_logging_name: String identifier which will be used within + the "name" field of logging records generated within the + "sqlalchemy.pool" logger. Defaults to a hexstring of the object's + id. + :param echo_pool=False: if True, the connection pool will log all checkouts/checkins to the logging stream, which defaults to sys.stdout. This flag ultimately controls a Python logger; see diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index ea6282954..095f7a960 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -169,6 +169,7 @@ class Dialect(object): Given a :class:`~sqlalchemy.engine.url.URL` object, returns a tuple consisting of a `*args`/`**kwargs` suitable to send directly to the dbapi's connect function. + """ raise NotImplementedError() @@ -183,6 +184,7 @@ class Dialect(object): The returned result is cached *per dialect class* so can contain no dialect-instance state. + """ raise NotImplementedError() @@ -192,6 +194,13 @@ class Dialect(object): Allows dialects to configure options based on server version info or other properties. + + The connection passed here is a SQLAlchemy Connection object, + with full capabilities. + + The initalize() method of the base dialect should be called via + super(). + """ pass @@ -204,6 +213,12 @@ class Dialect(object): properties from the database. If include_columns (a list or set) is specified, limit the autoload to the given column names. + + The default implementation uses the + :class:`~sqlalchemy.engine.reflection.Inspector` interface to + provide the output, building upon the granular table/column/ + constraint etc. methods of :class:`Dialect`. + """ raise NotImplementedError() @@ -458,8 +473,22 @@ class Dialect(object): raise NotImplementedError() - def visit_pool(self, pool): - """Executed after a pool is created.""" + def on_connect(self): + """return a callable which sets up a newly created DBAPI connection. + + The callable accepts a single argument "conn" which is the + DBAPI connection itself. It has no return value. + + This is used to set dialect-wide per-connection options such as isolation + modes, unicode modes, etc. + + If a callable is returned, it will be assembled into a pool listener + that receives the direct DBAPI connection, with all wrappers removed. + + If None is returned, no listener will be generated. + + """ + return None class ExecutionContext(object): @@ -1387,17 +1416,19 @@ class TwoPhaseTransaction(Transaction): self.connection._commit_twophase_impl(self.xid, self._is_prepared) -class Engine(Connectable): +class Engine(Connectable, log.Identified): """ Connects a :class:`~sqlalchemy.pool.Pool` and :class:`~sqlalchemy.engine.base.Dialect` together to provide a source of database connectivity and behavior. """ - def __init__(self, pool, dialect, url, echo=None, proxy=None): + def __init__(self, pool, dialect, url, logging_name=None, echo=None, proxy=None): self.pool = pool self.url = url self.dialect = dialect + if logging_name: + self.logging_name = logging_name self.echo = echo self.engine = self self.logger = log.instance_logger(self, echoflag=echo) diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 077627949..ce24a9ae4 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -135,28 +135,54 @@ class DefaultDialect(base.Dialect): self.default_schema_name = None self.returns_unicode_strings = self._check_unicode_returns(connection) - + + self.do_rollback(connection.connection) + + def on_connect(self): + """return a callable which sets up a newly created DBAPI connection. + + This is used to set dialect-wide per-connection options such as isolation + modes, unicode modes, etc. + + If a callable is returned, it will be assembled into a pool listener + that receives the direct DBAPI connection, with all wrappers removed. + + If None is returned, no listener will be generated. + + """ + return None + def _check_unicode_returns(self, connection): - cursor = connection.connection.cursor() + # Py2K + if self.supports_unicode_statements: + cast_to = unicode + else: + cast_to = str + # end Py2K + # Py3K + #cast_to = str def check_unicode(type_): - cursor.execute( - str( - expression.select( - [expression.cast( - expression.literal_column("'test unicode returns'"), type_) - ]).compile(dialect=self) + cursor = connection.connection.cursor() + try: + cursor.execute( + cast_to( + expression.select( + [expression.cast( + expression.literal_column("'test unicode returns'"), type_) + ]).compile(dialect=self) + ) ) - ) - - row = cursor.fetchone() - return isinstance(row[0], unicode) - + row = cursor.fetchone() + + return isinstance(row[0], unicode) + finally: + cursor.close() + # detect plain VARCHAR unicode_for_varchar = check_unicode(sqltypes.VARCHAR(60)) # detect if there's an NVARCHAR type with different behavior available unicode_for_unicode = check_unicode(sqltypes.Unicode(60)) - cursor.close() if unicode_for_unicode and not unicode_for_varchar: return "conditional" @@ -247,6 +273,7 @@ class DefaultExecutionContext(base.ExecutionContext): isinsert = False isupdate = False isdelete = False + isddl = False executemany = False result_map = None compiled = None @@ -266,6 +293,7 @@ class DefaultExecutionContext(base.ExecutionContext): if compiled_ddl is not None: self.compiled = compiled = compiled_ddl + self.isddl = True if compiled.statement._execution_options: self.execution_options = compiled.statement._execution_options diff --git a/lib/sqlalchemy/engine/strategies.py b/lib/sqlalchemy/engine/strategies.py index 7a8856ba8..7fc39b91a 100644 --- a/lib/sqlalchemy/engine/strategies.py +++ b/lib/sqlalchemy/engine/strategies.py @@ -90,7 +90,8 @@ class DefaultEngineStrategy(EngineStrategy): # consume pool arguments from kwargs, translating a few of # the arguments - translate = {'echo': 'echo_pool', + translate = {'logging_name': 'pool_logging_name', + 'echo': 'echo_pool', 'timeout': 'pool_timeout', 'recycle': 'pool_recycle', 'use_threadlocal':'pool_threadlocal'} @@ -129,8 +130,16 @@ class DefaultEngineStrategy(EngineStrategy): engine = engineclass(pool, dialect, u, **engine_args) if _initialize: - dialect.visit_pool(pool) - + do_on_connect = dialect.on_connect() + if do_on_connect: + def on_connect(conn, rec): + conn = getattr(conn, '_sqla_unwrap', conn) + if conn is None: + return + do_on_connect(conn) + + pool.add_listener({'first_connect': on_connect, 'connect':on_connect}) + def first_connect(conn, rec): c = base.Connection(engine, connection=conn) dialect.initialize(c) |
