[Sqlalchemy-commits] sqlalchemy: - why type.dialect_impl(dialect).bind_processor(dial...
Brought to you by:
zzzeek
From: <co...@sq...> - 2010-12-13 05:16:25
|
details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/bf7c2f853728 changeset: 7128:bf7c2f853728 user: zzzeek date: Mon Dec 13 00:15:32 2010 -0500 description: - why type.dialect_impl(dialect).bind_processor(dialect), caching just the impl? just call type._cached_bind_processor(dialect), cache the impl *and* the processor function. same for result sets. - use plain dict + update for defaultexecutioncontext.execution_options Subject: sqlalchemy: merge tip details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/cb91aa4d07e6 changeset: 7129:cb91aa4d07e6 user: zzzeek date: Mon Dec 13 00:16:04 2010 -0500 description: merge tip diffstat: lib/sqlalchemy/engine/base.py | 5 +- lib/sqlalchemy/engine/default.py | 25 ++---- lib/sqlalchemy/orm/mapper.py | 2 +- lib/sqlalchemy/schema.py | 6 +- lib/sqlalchemy/sql/compiler.py | 4 +- lib/sqlalchemy/sql/expression.py | 3 - lib/sqlalchemy/types.py | 131 +++++++++++++++++--------------- lib/sqlalchemy/util/_collections.py | 2 +- test/aaa_profiling/test_orm.py | 2 +- test/aaa_profiling/test_zoomark.py | 13 +- test/aaa_profiling/test_zoomark_orm.py | 4 +- 11 files changed, 96 insertions(+), 101 deletions(-) diffs (truncated from 446 to 300 lines): diff -r a113f378cc65 -r cb91aa4d07e6 lib/sqlalchemy/engine/base.py --- a/lib/sqlalchemy/engine/base.py Sun Dec 12 17:50:25 2010 -0500 +++ b/lib/sqlalchemy/engine/base.py Mon Dec 13 00:16:04 2010 -0500 @@ -701,7 +701,7 @@ """Return the string text of the generated SQL or DDL.""" return self.string or '' - + def construct_params(self, params=None): """Return the bind params for this compiled object. @@ -2221,8 +2221,7 @@ name, obj, type_ = \ colname, None, typemap.get(coltype, types.NULLTYPE) - processor = type_.dialect_impl(dialect).\ - result_processor(dialect, coltype) + processor = type_._cached_result_processor(dialect, coltype) processors.append(processor) rec = (processor, i) diff -r a113f378cc65 -r cb91aa4d07e6 lib/sqlalchemy/engine/default.py --- a/lib/sqlalchemy/engine/default.py Sun Dec 12 17:50:25 2010 -0500 +++ b/lib/sqlalchemy/engine/default.py Mon Dec 13 00:16:04 2010 -0500 @@ -307,7 +307,6 @@ class DefaultExecutionContext(base.ExecutionContext): - execution_options = util.frozendict() isinsert = False isupdate = False isdelete = False @@ -329,12 +328,10 @@ self.compiled = compiled = compiled_ddl self.isddl = True - if compiled.statement._execution_options: - self.execution_options = 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 - ) + self.execution_options = dict(self.execution_options) + self.execution_options.update(connection._execution_options) if not dialect.supports_unicode_statements: self.unicode_statement = unicode(compiled) @@ -366,12 +363,10 @@ 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 + self.execution_options = compiled.statement._execution_options if connection._execution_options: - self.execution_options = self.execution_options.union( - connection._execution_options - ) + self.execution_options = dict(self.execution_options) + self.execution_options.update(connection._execution_options) # compiled clauseelement. process bind params, process table defaults, # track collections used by ResultProxy to target and process results @@ -451,9 +446,7 @@ self.engine = connection.engine # plain text statement - if connection._execution_options: - self.execution_options = self.execution_options.\ - union(connection._execution_options) + self.execution_options = connection._execution_options if not parameters: if self.dialect.positional: @@ -493,9 +486,7 @@ 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.execution_options = connection._execution_options self.cursor = self.create_cursor() return self diff -r a113f378cc65 -r cb91aa4d07e6 lib/sqlalchemy/orm/mapper.py --- a/lib/sqlalchemy/orm/mapper.py Sun Dec 12 17:50:25 2010 -0500 +++ b/lib/sqlalchemy/orm/mapper.py Mon Dec 13 00:16:04 2010 -0500 @@ -2063,7 +2063,7 @@ util.warn( "Dialect %s does not support deleted rowcount " "- versioning cannot be verified." % - c.dialect.dialect_description, + connection.dialect.dialect_description, stacklevel=12) connection.execute(statement, del_objects) else: diff -r a113f378cc65 -r cb91aa4d07e6 lib/sqlalchemy/schema.py --- a/lib/sqlalchemy/schema.py Sun Dec 12 17:50:25 2010 -0500 +++ b/lib/sqlalchemy/schema.py Mon Dec 13 00:16:04 2010 -0500 @@ -504,7 +504,7 @@ usage within the :mod:`~sqlalchemy.ext.declarative` extension. :param type\_: The column's type, indicated using an instance which - subclasses :class:`~sqlalchemy.types.AbstractType`. If no arguments + subclasses :class:`~sqlalchemy.types.TypeEngine`. If no arguments are required for the type, the class of the type can be sent as well, e.g.:: @@ -684,9 +684,9 @@ if args: coltype = args[0] - if (isinstance(coltype, types.AbstractType) or + if (isinstance(coltype, types.TypeEngine) or (isinstance(coltype, type) and - issubclass(coltype, types.AbstractType))): + issubclass(coltype, types.TypeEngine))): if type_ is not None: raise exc.ArgumentError( "May not pass type_ positionally and as a keyword.") diff -r a113f378cc65 -r cb91aa4d07e6 lib/sqlalchemy/sql/compiler.py --- a/lib/sqlalchemy/sql/compiler.py Sun Dec 12 17:50:25 2010 -0500 +++ b/lib/sqlalchemy/sql/compiler.py Mon Dec 13 00:16:04 2010 -0500 @@ -262,7 +262,7 @@ self._memos[key] = processors = dict( (key, value) for key, value in ( (self.bind_names[bindparam], - bindparam.bind_processor(dialect)) + bindparam.type._cached_bind_processor(dialect)) for bindparam in self.bind_names ) if value is not None ) @@ -596,7 +596,7 @@ def render_literal_bindparam(self, bindparam, **kw): value = bindparam.value - processor = bindparam.bind_processor(self.dialect) + processor = bindparam.type._cached_bind_processor(self.dialect) if processor: value = processor(value) return self.render_literal_value(value, bindparam.type) diff -r a113f378cc65 -r cb91aa4d07e6 lib/sqlalchemy/sql/expression.py --- a/lib/sqlalchemy/sql/expression.py Sun Dec 12 17:50:25 2010 -0500 +++ b/lib/sqlalchemy/sql/expression.py Mon Dec 13 00:16:04 2010 -0500 @@ -2470,9 +2470,6 @@ self.key = _generated_label('%%(%d %s)s' % (id(self), self._orig_key or 'param')) - def bind_processor(self, dialect): - return self.type.dialect_impl(dialect).bind_processor(dialect) - def compare(self, other, **kw): """Compare this :class:`_BindParamClause` to the given clause.""" diff -r a113f378cc65 -r cb91aa4d07e6 lib/sqlalchemy/types.py --- a/lib/sqlalchemy/types.py Sun Dec 12 17:50:25 2010 -0500 +++ b/lib/sqlalchemy/types.py Mon Dec 13 00:16:04 2010 -0500 @@ -41,28 +41,43 @@ import array class AbstractType(Visitable): + """Base for all types - not needed except for backwards + compatibility.""" + +class TypeEngine(AbstractType): + """Base for built-in types.""" def copy_value(self, value): return value def bind_processor(self, dialect): - """Defines a bind parameter processing function. - + """Return a conversion function for processing bind values. + + Returns a callable which will receive a bind parameter value + as the sole positional argument and will return a value to + send to the DB-API. + + If processing is not necessary, the method should return ``None``. + :param dialect: Dialect instance in use. """ - return None def result_processor(self, dialect, coltype): - """Defines a result-column processing function. - + """Return a conversion function for processing result row values. + + Returns a callable which will receive a result row column + value as the sole positional argument and will return a value + to return to the user. + + If processing is not necessary, the method should return ``None``. + :param dialect: Dialect instance in use. :param coltype: DBAPI coltype argument received in cursor.description. - + """ - return None def compare_values(self, x, y): @@ -115,6 +130,44 @@ typ = t else: return self.__class__ + + @util.memoized_property + def _impl_dict(self): + return {} + + def __getstate__(self): + d = self.__dict__.copy() + d.pop('_impl_dict', None) + return d + + def dialect_impl(self, dialect, **kwargs): + key = dialect.__class__, dialect.server_version_info + try: + return self._impl_dict[key] + except KeyError: + return self._impl_dict.setdefault(key, + dialect.type_descriptor(self)) + + def _cached_bind_processor(self, dialect): + key = "bind", dialect.__class__, dialect.server_version_info + try: + return self._impl_dict[key] + except KeyError: + self._impl_dict[key] = bp = \ + self.dialect_impl(dialect).bind_processor(dialect) + return bp + + def _cached_result_processor(self, dialect, coltype): + key = "result", dialect.__class__, dialect.server_version_info, coltype + try: + return self._impl_dict[key] + except KeyError: + self._impl_dict[key] = rp = self.dialect_impl(dialect).\ + result_processor(dialect, coltype) + return rp + + def adapt(self, cls): + return cls() def _coerce_compared_value(self, op, value): _coerced_type = _type_map.get(type(value), NULLTYPE) @@ -164,52 +217,6 @@ ", ".join("%s=%r" % (k, getattr(self, k, None)) for k in inspect.getargspec(self.__init__)[0][1:])) -class TypeEngine(AbstractType): - """Base for built-in types.""" - - @util.memoized_property - def _impl_dict(self): - return {} - - def dialect_impl(self, dialect, **kwargs): - key = dialect.__class__, dialect.server_version_info - try: - return self._impl_dict[key] - except KeyError: - return self._impl_dict.setdefault(key, - dialect.type_descriptor(self)) - - def __getstate__(self): - d = self.__dict__.copy() - d.pop('_impl_dict', None) - return d - - def bind_processor(self, dialect): - """Return a conversion function for processing bind values. - - Returns a callable which will receive a bind parameter value - as the sole positional argument and will return a value to - send to the DB-API. - - If processing is not necessary, the method should return ``None``. - - """ - return None - - def result_processor(self, dialect, coltype): - """Return a conversion function for processing result row values. - - Returns a callable which will receive a result row column - value as the sole positional argument and will return a value - to return to the user. - - If processing is not necessary, the method should return ``None``. |