diff options
Diffstat (limited to 'lib/sqlalchemy/engine/base.py')
-rw-r--r-- | lib/sqlalchemy/engine/base.py | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 583a02763..2ca2ac5f7 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -13,7 +13,7 @@ and result contexts. """ import inspect, StringIO, sys -from sqlalchemy import exceptions, schema, util, types, logging +from sqlalchemy import exc, schema, util, types, log from sqlalchemy.sql import expression @@ -451,7 +451,7 @@ class Compiled(object): self.statement = statement self.column_keys = column_keys self.bind = bind - self.can_execute = statement.supports_execution() + self.can_execute = statement.supports_execution def compile(self): """Produce the internal string representation of this element.""" @@ -482,7 +482,7 @@ class Compiled(object): e = self.bind if e is None: - raise exceptions.UnboundExecutionError("This Compiled object is not bound to any Engine or Connection.") + raise exc.UnboundExecutionError("This Compiled object is not bound to any Engine or Connection.") return e._execute_compiled(self, multiparams, params) def scalar(self, *multiparams, **params): @@ -541,7 +541,7 @@ class Connection(Connectable): self.__savepoint_seq = 0 self.__branch = _branch self.__invalid = False - + def _branch(self): """Return a new Connection which references this Connection's engine and connection; but does not have close_with_result enabled, @@ -550,7 +550,7 @@ class Connection(Connectable): This is used to execute "sub" statements within a single execution, usually an INSERT statement. """ - return Connection(self.engine, self.__connection, _branch=True) + return self.engine.Connection(self.engine, self.__connection, _branch=True) def dialect(self): "Dialect used by this Connection." @@ -578,11 +578,11 @@ class Connection(Connectable): except AttributeError: if self.__invalid: if self.__transaction is not None: - raise exceptions.InvalidRequestError("Can't reconnect until invalid transaction is rolled back") + raise exc.InvalidRequestError("Can't reconnect until invalid transaction is rolled back") self.__connection = self.engine.raw_connection() self.__invalid = False return self.__connection - raise exceptions.InvalidRequestError("This Connection is closed") + raise exc.InvalidRequestError("This Connection is closed") connection = property(connection) def should_close_with_result(self): @@ -702,7 +702,7 @@ class Connection(Connectable): """ if self.__transaction is not None: - raise exceptions.InvalidRequestError( + raise exc.InvalidRequestError( "Cannot start a two phase transaction when a transaction " "is already in progress.") if xid is None: @@ -843,7 +843,7 @@ class Connection(Connectable): if c in Connection.executors: return Connection.executors[c](self, object, multiparams, params) else: - raise exceptions.InvalidRequestError("Unexecutable object type: " + str(type(object))) + raise exc.InvalidRequestError("Unexecutable object type: " + str(type(object))) def _execute_default(self, default, multiparams=None, params=None): return self.engine.dialect.defaultrunner(self.__create_execution_context()).traverse_single(default) @@ -862,7 +862,7 @@ class Connection(Connectable): in the case of 'raw' execution which accepts positional parameters, it may be a list of tuples or lists.""" - if multiparams is None or len(multiparams) == 0: + if not multiparams: if params: return [params] else: @@ -897,7 +897,7 @@ class Connection(Connectable): def _execute_compiled(self, compiled, multiparams=None, params=None, distilled_params=None): """Execute a sql.Compiled object.""" if not compiled.can_execute: - raise exceptions.ArgumentError("Not an executable clause: %s" % (str(compiled))) + raise exc.ArgumentError("Not an executable clause: %s" % (str(compiled))) if distilled_params is None: distilled_params = self.__distill_params(multiparams, params) @@ -924,7 +924,7 @@ class Connection(Connectable): def _handle_dbapi_exception(self, e, statement, parameters, cursor): if getattr(self, '_reentrant_error', False): - raise exceptions.DBAPIError.instance(None, None, e) + raise exc.DBAPIError.instance(None, None, e) self._reentrant_error = True try: if not isinstance(e, self.dialect.dbapi.Error): @@ -939,7 +939,7 @@ class Connection(Connectable): self._autorollback() if self.__close_with_result: self.close() - raise exceptions.DBAPIError.instance(statement, parameters, e, connection_invalidated=is_disconnect) + raise exc.DBAPIError.instance(statement, parameters, e, connection_invalidated=is_disconnect) finally: del self._reentrant_error @@ -1047,7 +1047,7 @@ class Transaction(object): def commit(self): if not self._parent._is_active: - raise exceptions.InvalidRequestError("This transaction is inactive") + raise exc.InvalidRequestError("This transaction is inactive") self._do_commit() self._is_active = False @@ -1094,7 +1094,7 @@ class TwoPhaseTransaction(Transaction): def prepare(self): if not self._parent._is_active: - raise exceptions.InvalidRequestError("This transaction is inactive") + raise exc.InvalidRequestError("This transaction is inactive") self._connection._prepare_twophase_impl(self.xid) self._is_prepared = True @@ -1110,13 +1110,17 @@ class Engine(Connectable): provide a default implementation of SchemaEngine. """ - def __init__(self, pool, dialect, url, echo=None): + def __init__(self, pool, dialect, url, echo=None, proxy=None): self.pool = pool self.url = url - self.dialect=dialect + self.dialect = dialect self.echo = echo self.engine = self - self.logger = logging.instance_logger(self, echoflag=echo) + self.logger = log.instance_logger(self, echoflag=echo) + if proxy: + self.Connection = _proxy_connection_cls(Connection, proxy) + else: + self.Connection = Connection def name(self): "String name of the [sqlalchemy.engine#Dialect] in use by this ``Engine``." @@ -1124,7 +1128,7 @@ class Engine(Connectable): return sys.modules[self.dialect.__module__].descriptor()['name'] name = property(name) - echo = logging.echo_property() + echo = log.echo_property() def __repr__(self): return 'Engine(%s)' % str(self.url) @@ -1228,7 +1232,7 @@ class Engine(Connectable): def connect(self, **kwargs): """Return a newly allocated Connection object.""" - return Connection(self, **kwargs) + return self.Connection(self, **kwargs) def contextual_connect(self, close_with_result=False, **kwargs): """Return a Connection object which may be newly allocated, or may be part of some ongoing context. @@ -1236,7 +1240,7 @@ class Engine(Connectable): This Connection is meant to be used by the various "auto-connecting" operations. """ - return Connection(self, self.pool.connect(), close_with_result=close_with_result, **kwargs) + return self.Connection(self, self.pool.connect(), close_with_result=close_with_result, **kwargs) def table_names(self, schema=None, connection=None): """Return a list of all table names available in the database. @@ -1286,6 +1290,22 @@ class Engine(Connectable): return self.pool.unique_connection() +def _proxy_connection_cls(cls, proxy): + class ProxyConnection(cls): + def execute(self, object, *multiparams, **params): + return proxy.execute(self, super(ProxyConnection, self).execute, object, *multiparams, **params) + + def execute_clauseelement(self, elem, multiparams=None, params=None): + return proxy.execute(self, super(ProxyConnection, self).execute, elem, *(multiparams or []), **(params or {})) + + def _cursor_execute(self, cursor, statement, parameters, context=None): + return proxy.cursor_execute(super(ProxyConnection, self)._cursor_execute, cursor, statement, parameters, context, False) + + def _cursor_executemany(self, cursor, statement, parameters, context=None): + return proxy.cursor_execute(super(ProxyConnection, self)._cursor_executemany, cursor, statement, parameters, context, True) + + return ProxyConnection + class RowProxy(object): """Proxy a single cursor row for a parent ResultProxy. @@ -1296,6 +1316,8 @@ class RowProxy(object): results that correspond to constructed SQL expressions). """ + __slots__ = ['__parent', '__row'] + def __init__(self, parent, row): """RowProxy objects are constructed by ResultProxy objects.""" @@ -1488,14 +1510,14 @@ class ResultProxy(object): return props[key._label.lower()] elif hasattr(key, 'name') and key.name.lower() in props: return props[key.name.lower()] - raise exceptions.NoSuchColumnError("Could not locate column in row for column '%s'" % (str(key))) + raise exc.NoSuchColumnError("Could not locate column in row for column '%s'" % (str(key))) return rec return util.PopulateDict(lookup_key) def __ambiguous_processor(self, colname): def process(value): - raise exceptions.InvalidRequestError("Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % colname) + raise exc.InvalidRequestError("Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % colname) return process def close(self): |