summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-12-05 01:41:37 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2010-12-05 01:41:37 -0500
commitbbe88372e8a6f4f96a3492b670732e10edacf282 (patch)
tree6666ebd3b11d363dc33d9ac57d9d298748b7d45f /lib/sqlalchemy/engine
parent8e24584d8d242d40d605752116ac05be33f697d3 (diff)
downloadsqlalchemy-bbe88372e8a6f4f96a3492b670732e10edacf282.tar.gz
- inline the various construction methods of DefaultExecutionContext. This
makes it sort of easier to read, sort of harder, depending on where you look. Cuts down two or three method calls on execute.
Diffstat (limited to 'lib/sqlalchemy/engine')
-rw-r--r--lib/sqlalchemy/engine/base.py88
-rw-r--r--lib/sqlalchemy/engine/default.py344
2 files changed, 246 insertions, 186 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index 267249971..77aa950c0 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -1228,63 +1228,100 @@ class Connection(Connectable):
return [multiparams]
def _execute_function(self, func, multiparams, params):
+ """Execute a sql.FunctionElement object."""
+
return self._execute_clauseelement(func.select(), multiparams, params)
def _execute_default(self, default, multiparams, params):
- ctx = self.__create_execution_context()
+ """Execute a schema.ColumnDefault object."""
+
+ try:
+ dialect = self.engine.dialect
+ ctx = dialect.execution_ctx_cls._init_default(
+ dialect, self)
+ except Exception, e:
+ self._handle_dbapi_exception(e, None, None, None, None)
+ raise
+
ret = ctx._exec_default(default)
if self.should_close_with_result:
self.close()
return ret
def _execute_ddl(self, ddl, params, multiparams):
- context = self.__create_execution_context(
- compiled_ddl=ddl.compile(dialect=self.dialect),
- parameters=None
- )
+ """Execute a schema.DDL object."""
+
+ try:
+ dialect = self.engine.dialect
+ context = dialect.execution_ctx_cls.\
+ _init_ddl(
+ dialect,
+ self,
+ ddl.compile(dialect=self.dialect))
+ except Exception, e:
+ self._handle_dbapi_exception(e, None, None, None, None)
+ raise
return self.__execute_context(context)
def _execute_clauseelement(self, elem, multiparams, params):
+ """Execute a sql.ClauseElement object."""
+
params = self.__distill_params(multiparams, params)
if params:
keys = params[0].keys()
else:
keys = []
+ dialect = self.engine.dialect
if 'compiled_cache' in self._execution_options:
- key = self.dialect, elem, tuple(keys), len(params) > 1
+ key = dialect, elem, tuple(keys), len(params) > 1
if key in self._execution_options['compiled_cache']:
compiled_sql = self._execution_options['compiled_cache'][key]
else:
compiled_sql = elem.compile(
- dialect=self.dialect, column_keys=keys,
+ dialect=dialect, column_keys=keys,
inline=len(params) > 1)
self._execution_options['compiled_cache'][key] = compiled_sql
else:
compiled_sql = elem.compile(
- dialect=self.dialect, column_keys=keys,
+ dialect=dialect, column_keys=keys,
inline=len(params) > 1)
- context = self.__create_execution_context(
- compiled_sql=compiled_sql,
- parameters=params
- )
+ try:
+ context = dialect.execution_ctx_cls.\
+ _init_compiled(dialect, self, compiled_sql, params)
+ except Exception, e:
+ self._handle_dbapi_exception(e, None, params, None, None)
+ raise
return self.__execute_context(context)
def _execute_compiled(self, compiled, multiparams, params):
"""Execute a sql.Compiled object."""
- context = self.__create_execution_context(
- compiled_sql=compiled,
- parameters=self.__distill_params(multiparams, params)
- )
+ try:
+ dialect = self.engine.dialect
+ parameters=self.__distill_params(multiparams, params)
+ context = dialect.execution_ctx_cls.\
+ _init_compiled(dialect, self,
+ compiled, parameters)
+ except Exception, e:
+ self._handle_dbapi_exception(e, None, parameters, None, None)
+ raise
return self.__execute_context(context)
def _execute_text(self, statement, multiparams, params):
+ """Execute a string SQL statement."""
+
parameters = self.__distill_params(multiparams, params)
- context = self.__create_execution_context(
- statement=statement,
- parameters=parameters)
+ try:
+ dialect = self.engine.dialect
+ context = dialect.execution_ctx_cls.\
+ _init_statement(dialect, self,
+ statement, parameters)
+ except Exception, e:
+ self._handle_dbapi_exception(e, statement, parameters,
+ None, None)
+ raise
return self.__execute_context(context)
def __execute_context(self, context):
@@ -1387,19 +1424,6 @@ class Connection(Connectable):
finally:
del self._reentrant_error
- def __create_execution_context(self, **kwargs):
- try:
- dialect = self.engine.dialect
- return dialect.execution_ctx_cls(
- dialect,
- connection=self, **kwargs)
- except Exception, e:
- self._handle_dbapi_exception(e,
- kwargs.get('statement', None),
- kwargs.get('parameters', None),
- None, None)
- raise
-
def _cursor_execute(self, cursor, statement, parameters, context=None):
if self._echo:
self.engine.logger.info(statement)
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index 6c708aa52..ebc001821 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -317,106 +317,190 @@ class DefaultExecutionContext(base.ExecutionContext):
compiled = None
statement = None
- def __init__(self,
- dialect,
- connection,
- compiled_sql=None,
- compiled_ddl=None,
- statement=None,
- parameters=None):
+ @classmethod
+ def _init_ddl(cls, dialect, connection, compiled_ddl):
+ """Initialize execution context for a DDLElement construct."""
+ self = cls.__new__(cls)
self.dialect = dialect
self._connection = self.root_connection = connection
self.engine = connection.engine
+
+ self.compiled = compiled = compiled_ddl
+ self.isddl = True
+
+ if compiled.statement._execution_options:
+ self.execution_options = compiled.statement._execution_options
+ if connection._execution_options:
+ self.execution_options = self.execution_options.union(
+ connection._execution_options
+ )
+
+ if not dialect.supports_unicode_statements:
+ self.unicode_statement = unicode(compiled)
+ self.statement = self.unicode_statement.encode(self.dialect.encoding)
+ else:
+ self.statement = self.unicode_statement = unicode(compiled)
+
+ self.cursor = self.create_cursor()
+ self.compiled_parameters = []
+
+ if dialect.positional:
+ self.parameters = [dialect.execute_sequence_format()]
+ else:
+ self.parameters = [{}]
+
+ return self
- 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
- if connection._execution_options:
- self.execution_options = self.execution_options.union(
+ @classmethod
+ def _init_compiled(cls, dialect, connection, compiled, parameters):
+ """Initialize execution context for a Compiled construct."""
+
+ self = cls.__new__(cls)
+ self.dialect = dialect
+ self._connection = self.root_connection = connection
+ self.engine = connection.engine
+
+ self.compiled = compiled
+
+ if not compiled.can_execute:
+ raise exc.ArgumentError("Not an executable clause: %s" % compiled)
+
+ if compiled.statement._execution_options:
+ self.execution_options = compiled.statement._execution_options
+ if connection._execution_options:
+ self.execution_options = self.execution_options.union(
connection._execution_options
)
- if not dialect.supports_unicode_statements:
- self.unicode_statement = unicode(compiled)
- self.statement = self.unicode_statement.encode(self.dialect.encoding)
- else:
- self.statement = self.unicode_statement = unicode(compiled)
-
- self.cursor = self.create_cursor()
- self.compiled_parameters = []
- self.parameters = [self._default_params]
-
- elif compiled_sql is not None:
- self.compiled = compiled = compiled_sql
-
- if not compiled.can_execute:
- raise exc.ArgumentError("Not an executable clause: %s" % compiled)
-
- if compiled.statement._execution_options:
- self.execution_options = compiled.statement._execution_options
- if connection._execution_options:
- self.execution_options = self.execution_options.union(
- connection._execution_options
- )
-
- # compiled clauseelement. process bind params, process table defaults,
- # track collections used by ResultProxy to target and process results
-
- self.processors = dict(
- (key, value) for key, value in
- ( (compiled.bind_names[bindparam],
- bindparam.bind_processor(self.dialect))
- for bindparam in compiled.bind_names )
- if value is not None)
-
- self.result_map = compiled.result_map
-
- if not dialect.supports_unicode_statements:
- self.unicode_statement = unicode(compiled)
- self.statement = self.unicode_statement.encode(self.dialect.encoding)
- else:
- self.statement = self.unicode_statement = unicode(compiled)
+ # compiled clauseelement. process bind params, process table defaults,
+ # track collections used by ResultProxy to target and process results
- self.isinsert = compiled.isinsert
- self.isupdate = compiled.isupdate
- self.isdelete = compiled.isdelete
+ self.result_map = compiled.result_map
- if not parameters:
- self.compiled_parameters = [compiled.construct_params()]
- else:
- self.compiled_parameters = [compiled.construct_params(m, _group_number=grp) for
- grp,m in enumerate(parameters)]
-
- self.executemany = len(parameters) > 1
-
- self.cursor = self.create_cursor()
- if self.isinsert or self.isupdate:
- self.__process_defaults()
- self.parameters = self.__convert_compiled_params(self.compiled_parameters)
-
- elif statement is not None:
- # plain text statement
- if connection._execution_options:
- self.execution_options = self.execution_options.union(connection._execution_options)
- self.parameters = self.__encode_param_keys(parameters)
+ self.unicode_statement = unicode(compiled)
+ if not dialect.supports_unicode_statements:
+ self.statement = self.unicode_statement.encode(self.dialect.encoding)
+ else:
+ self.statement = self.unicode_statement
+
+ self.isinsert = compiled.isinsert
+ self.isupdate = compiled.isupdate
+ self.isdelete = compiled.isdelete
+
+ if not parameters:
+ self.compiled_parameters = [compiled.construct_params()]
+ else:
+ self.compiled_parameters = \
+ [compiled.construct_params(m, _group_number=grp) for
+ grp,m in enumerate(parameters)]
+
self.executemany = len(parameters) > 1
+
+ self.cursor = self.create_cursor()
+ if self.isinsert or self.isupdate:
+ self.__process_defaults()
- if not dialect.supports_unicode_statements and isinstance(statement, unicode):
- self.unicode_statement = statement
- self.statement = statement.encode(self.dialect.encoding)
+ processors = dict(
+ (key, value) for key, value in
+ ( (compiled.bind_names[bindparam],
+ bindparam.bind_processor(dialect))
+ for bindparam in compiled.bind_names )
+ if value is not None)
+
+ # Convert the dictionary of bind parameter values
+ # into a dict or list to be sent to the DBAPI's
+ # execute() or executemany() method.
+ parameters = []
+ if dialect.positional:
+ for compiled_params in self.compiled_parameters:
+ param = []
+ for key in self.compiled.positiontup:
+ if key in processors:
+ param.append(processors[key](compiled_params[key]))
+ else:
+ param.append(compiled_params[key])
+ parameters.append(dialect.execute_sequence_format(param))
+ else:
+ encode = not dialect.supports_unicode_statements
+ for compiled_params in self.compiled_parameters:
+ param = {}
+ if encode:
+ encoding = dialect.encoding
+ for key in compiled_params:
+ if key in processors:
+ param[key.encode(encoding)] = \
+ processors[key](compiled_params[key])
+ else:
+ param[key.encode(encoding)] = compiled_params[key]
+ else:
+ for key in compiled_params:
+ if key in processors:
+ param[key] = processors[key](compiled_params[key])
+ else:
+ param[key] = compiled_params[key]
+ parameters.append(param)
+ self.parameters = dialect.execute_sequence_format(parameters)
+
+ return self
+
+ @classmethod
+ def _init_statement(cls, dialect, connection, statement, parameters):
+ """Initialize execution context for a string SQL statement."""
+
+ self = cls.__new__(cls)
+ self.dialect = dialect
+ self._connection = self.root_connection = connection
+ self.engine = connection.engine
+
+ # plain text statement
+ if connection._execution_options:
+ self.execution_options = self.execution_options.\
+ union(connection._execution_options)
+
+ if not parameters:
+ if self.dialect.positional:
+ self.parameters = [dialect.execute_sequence_format()]
else:
- self.statement = self.unicode_statement = statement
-
- self.cursor = self.create_cursor()
+ self.parameters = [{}]
+ elif isinstance(parameters[0], dialect.execute_sequence_format):
+ self.parameters = parameters
+ elif isinstance(parameters[0], dict):
+ if dialect.supports_unicode_statements:
+ self.parameters = parameters
+ else:
+ self.parameters= [
+ dict((k.encode(dialect.encoding), d[k]) for k in d)
+ for d in parameters
+ ] or [{}]
+ else:
+ self.parameters = [dialect.execute_sequence_format(p)
+ for p in parameters]
+
+ self.executemany = len(parameters) > 1
+
+ if not dialect.supports_unicode_statements and isinstance(statement, unicode):
+ self.unicode_statement = statement
+ self.statement = statement.encode(self.dialect.encoding)
else:
- # no statement. used for standalone ColumnDefault execution.
- if connection._execution_options:
- self.execution_options = self.execution_options.union(connection._execution_options)
- self.cursor = self.create_cursor()
+ self.statement = self.unicode_statement = statement
+
+ self.cursor = self.create_cursor()
+ return self
+
+ @classmethod
+ def _init_default(cls, dialect, connection):
+ """Initialize execution context for a ColumnDefault construct."""
+
+ self = cls.__new__(cls)
+ self.dialect = dialect
+ self._connection = self.root_connection = connection
+ self.engine = connection.engine
+ if connection._execution_options:
+ self.execution_options = self.execution_options.\
+ union(connection._execution_options)
+ self.cursor = self.create_cursor()
+ return self
@util.memoized_property
def is_crud(self):
@@ -446,13 +530,6 @@ class DefaultExecutionContext(base.ExecutionContext):
bool(self.compiled.returning) and \
not self.compiled.statement._returning
- @util.memoized_property
- def _default_params(self):
- if self.dialect.positional:
- return self.dialect.execute_sequence_format()
- else:
- return {}
-
def _execute_scalar(self, stmt):
"""Execute a string statement on the current cursor, returning a
scalar result.
@@ -466,70 +543,20 @@ class DefaultExecutionContext(base.ExecutionContext):
conn = self._connection
if isinstance(stmt, unicode) and not self.dialect.supports_unicode_statements:
stmt = stmt.encode(self.dialect.encoding)
- conn._cursor_execute(self.cursor, stmt, self._default_params)
+
+ if self.dialect.positional:
+ default_params = self.dialect.execute_sequence_format()
+ else:
+ default_params = {}
+
+ conn._cursor_execute(self.cursor, stmt, default_params)
return self.cursor.fetchone()[0]
@property
def connection(self):
return self._connection._branch()
- def __encode_param_keys(self, params):
- """Apply string encoding to the keys of dictionary-based bind parameters.
- This is only used executing textual, non-compiled SQL expressions.
-
- """
-
- if not params:
- return [self._default_params]
- elif isinstance(params[0], self.dialect.execute_sequence_format):
- return params
- elif isinstance(params[0], dict):
- if self.dialect.supports_unicode_statements:
- return params
- else:
- def proc(d):
- return dict((k.encode(self.dialect.encoding), d[k]) for k in d)
- return [proc(d) for d in params] or [{}]
- else:
- return [self.dialect.execute_sequence_format(p) for p in params]
-
-
- def __convert_compiled_params(self, compiled_parameters):
- """Convert the dictionary of bind parameter values into a dict or list
- to be sent to the DBAPI's execute() or executemany() method.
- """
-
- processors = self.processors
- parameters = []
- if self.dialect.positional:
- for compiled_params in compiled_parameters:
- param = []
- for key in self.compiled.positiontup:
- if key in processors:
- param.append(processors[key](compiled_params[key]))
- else:
- param.append(compiled_params[key])
- parameters.append(self.dialect.execute_sequence_format(param))
- else:
- encode = not self.dialect.supports_unicode_statements
- for compiled_params in compiled_parameters:
- param = {}
- if encode:
- encoding = self.dialect.encoding
- for key in compiled_params:
- if key in processors:
- param[key.encode(encoding)] = processors[key](compiled_params[key])
- else:
- param[key.encode(encoding)] = compiled_params[key]
- else:
- for key in compiled_params:
- if key in processors:
- param[key] = processors[key](compiled_params[key])
- else:
- param[key] = compiled_params[key]
- parameters.append(param)
- return self.dialect.execute_sequence_format(parameters)
def should_autocommit_text(self, statement):
return AUTOCOMMIT_REGEXP.match(statement)
@@ -624,6 +651,10 @@ class DefaultExecutionContext(base.ExecutionContext):
"""Given a cursor and ClauseParameters, call the appropriate
style of ``setinputsizes()`` on the cursor, using DB-API types
from the bind parameter's ``TypeEngine`` objects.
+
+ This method only called by those dialects which require it,
+ currently cx_oracle.
+
"""
if not hasattr(self.compiled, 'bind_names'):
@@ -696,7 +727,8 @@ class DefaultExecutionContext(base.ExecutionContext):
scalar_defaults = {}
# pre-determine scalar Python-side defaults
- # to avoid many calls of get_insert_default()/get_update_default()
+ # to avoid many calls of get_insert_default()/
+ # get_update_default()
for c in self.compiled.prefetch:
if self.isinsert and c.default and c.default.is_scalar:
scalar_defaults[c] = c.default.arg
@@ -717,7 +749,8 @@ class DefaultExecutionContext(base.ExecutionContext):
del self.current_parameters
else:
- self.current_parameters = compiled_parameters = self.compiled_parameters[0]
+ self.current_parameters = compiled_parameters = \
+ self.compiled_parameters[0]
for c in self.compiled.prefetch:
if self.isinsert:
@@ -730,8 +763,11 @@ class DefaultExecutionContext(base.ExecutionContext):
del self.current_parameters
if self.isinsert:
- self._inserted_primary_key = [compiled_parameters.get(c.key, None)
- for c in self.compiled.statement.table.primary_key]
+ self._inserted_primary_key = [
+ compiled_parameters.get(c.key, None)
+ for c in self.compiled.\
+ statement.table.primary_key
+ ]
self._last_inserted_params = compiled_parameters
else:
self._last_updated_params = compiled_parameters