summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-05-09 16:34:10 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-05-09 16:34:10 +0000
commit4a6afd469fad170868554bf28578849bf3dfd5dd (patch)
treeb396edc33d567ae19dd244e87137296450467725 /lib/sqlalchemy/engine
parent46b7c9dc57a38d5b9e44a4723dad2ad8ec57baca (diff)
downloadsqlalchemy-4a6afd469fad170868554bf28578849bf3dfd5dd.tar.gz
r4695 merged to trunk; trunk now becomes 0.5.
0.4 development continues at /sqlalchemy/branches/rel_0_4
Diffstat (limited to 'lib/sqlalchemy/engine')
-rw-r--r--lib/sqlalchemy/engine/base.py68
-rw-r--r--lib/sqlalchemy/engine/default.py11
-rw-r--r--lib/sqlalchemy/engine/strategies.py6
-rw-r--r--lib/sqlalchemy/engine/threadlocal.py15
-rw-r--r--lib/sqlalchemy/engine/url.py6
5 files changed, 68 insertions, 38 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):
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index 3c1721f9d..e39cbdd39 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -12,7 +12,6 @@ as the base class for their own corresponding classes.
"""
-
import re, random
from sqlalchemy.engine import base
from sqlalchemy.sql import compiler, expression
@@ -112,7 +111,7 @@ class DefaultDialect(base.Dialect):
This id will be passed to do_begin_twophase(), do_rollback_twophase(),
do_commit_twophase(). Its format is unspecified."""
- return "_sa_%032x" % random.randint(0,2**128)
+ return "_sa_%032x" % random.randint(0, 2 ** 128)
def do_savepoint(self, connection, name):
connection.execute(expression.SavepointClause(name))
@@ -331,9 +330,9 @@ class DefaultExecutionContext(base.ExecutionContext):
if self.dialect.positional:
inputsizes = []
for key in self.compiled.positiontup:
- typeengine = types[key]
- dbtype = typeengine.dialect_impl(self.dialect).get_dbapi_type(self.dialect.dbapi)
- if dbtype is not None:
+ typeengine = types[key]
+ dbtype = typeengine.dialect_impl(self.dialect).get_dbapi_type(self.dialect.dbapi)
+ if dbtype is not None:
inputsizes.append(dbtype)
try:
self.cursor.setinputsizes(*inputsizes)
@@ -395,4 +394,4 @@ class DefaultExecutionContext(base.ExecutionContext):
self._last_updated_params = compiled_parameters
self.postfetch_cols = self.compiled.postfetch
- self.prefetch_cols = self.compiled.prefetch \ No newline at end of file
+ self.prefetch_cols = self.compiled.prefetch
diff --git a/lib/sqlalchemy/engine/strategies.py b/lib/sqlalchemy/engine/strategies.py
index d4a0ad841..aab191231 100644
--- a/lib/sqlalchemy/engine/strategies.py
+++ b/lib/sqlalchemy/engine/strategies.py
@@ -12,7 +12,7 @@ classes.
from sqlalchemy.engine import base, threadlocal, url
-from sqlalchemy import util, exceptions
+from sqlalchemy import util, exc
from sqlalchemy import pool as poollib
strategies = {}
@@ -77,7 +77,7 @@ class DefaultEngineStrategy(EngineStrategy):
try:
return dbapi.connect(*cargs, **cparams)
except Exception, e:
- raise exceptions.DBAPIError.instance(None, None, e)
+ raise exc.DBAPIError.instance(None, None, e)
creator = kwargs.pop('creator', connect)
poolclass = (kwargs.pop('poolclass', None) or
@@ -200,7 +200,7 @@ class MockEngineStrategy(EngineStrategy):
def create(self, entity, **kwargs):
kwargs['checkfirst'] = False
- self.dialect.schemagenerator(self.dialect ,self, **kwargs).traverse(entity)
+ self.dialect.schemagenerator(self.dialect, self, **kwargs).traverse(entity)
def drop(self, entity, **kwargs):
kwargs['checkfirst'] = False
diff --git a/lib/sqlalchemy/engine/threadlocal.py b/lib/sqlalchemy/engine/threadlocal.py
index e4b2859dc..91b16ed5f 100644
--- a/lib/sqlalchemy/engine/threadlocal.py
+++ b/lib/sqlalchemy/engine/threadlocal.py
@@ -17,7 +17,7 @@ class TLSession(object):
try:
return self.__transaction._increment_connect()
except AttributeError:
- return TLConnection(self, self.engine.pool.connect(), close_with_result=close_with_result)
+ return self.engine.TLConnection(self, self.engine.pool.connect(), close_with_result=close_with_result)
def reset(self):
try:
@@ -81,11 +81,14 @@ class TLSession(object):
class TLConnection(base.Connection):
- def __init__(self, session, connection, close_with_result):
- base.Connection.__init__(self, session.engine, connection, close_with_result=close_with_result)
+ def __init__(self, session, connection, **kwargs):
+ base.Connection.__init__(self, session.engine, connection, **kwargs)
self.__session = session
self.__opencount = 1
+ def _branch(self):
+ return self.engine.Connection(self.engine, self.connection, _branch=True)
+
def session(self):
return self.__session
session = property(session)
@@ -168,6 +171,12 @@ class TLEngine(base.Engine):
super(TLEngine, self).__init__(*args, **kwargs)
self.context = util.ThreadLocal()
+ proxy = kwargs.get('proxy')
+ if proxy:
+ self.TLConnection = base._proxy_connection_cls(TLConnection, proxy)
+ else:
+ self.TLConnection = TLConnection
+
def session(self):
"Returns the current thread's TLSession"
if not hasattr(self.context, 'session'):
diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py
index 7364f0227..72d09bf85 100644
--- a/lib/sqlalchemy/engine/url.py
+++ b/lib/sqlalchemy/engine/url.py
@@ -7,7 +7,7 @@ be used directly and is also accepted directly by ``create_engine()``.
"""
import re, cgi, sys, urllib
-from sqlalchemy import exceptions
+from sqlalchemy import exc
class URL(object):
@@ -53,7 +53,7 @@ class URL(object):
self.port = int(port)
else:
self.port = None
- self.database= database
+ self.database = database
self.query = query or {}
def __str__(self):
@@ -180,7 +180,7 @@ def _parse_rfc1738_args(name):
name = components.pop('name')
return URL(name, **components)
else:
- raise exceptions.ArgumentError(
+ raise exc.ArgumentError(
"Could not parse rfc1738 URL from string '%s'" % name)
def _parse_keyvalue_args(name):