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
"""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.
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)
class DefaultExecutionContext(base.ExecutionContext):
- execution_options = util.frozendict()
isinsert = False
isupdate = False
isdelete = False
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)
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
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:
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
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.::
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.")
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
)
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)
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."""
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):
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)
", ".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``.
-
- """
- return None
-
- def adapt(self, cls):
- return cls()
class UserDefinedType(TypeEngine):
"""Base for user defined types.
"""
return op
-class TypeDecorator(AbstractType):
+class TypeDecorator(TypeEngine):
"""Allows the creation of types which add additional functionality
to an existing type.
"type being decorated")
self.impl = to_instance(self.__class__.impl, *args, **kwargs)
- def adapt(self, cls):
- return cls()
-
def dialect_impl(self, dialect):
key = (dialect.__class__, dialect.server_version_info)
self._impl_dict[key] = tt
return tt
- @util.memoized_property
- def _impl_dict(self):
- return {}
-
@util.memoized_property
def _type_affinity(self):
return self.impl._type_affinity
def bind_processor(self, dialect):
DBAPIBinary = dialect.dbapi.Binary
def process(value):
+ x = self
if value is not None:
return DBAPIBinary(value)
else:
self.mutable = mutable
self.comparator = comparator
super(PickleType, self).__init__()
-
+
+ def __reduce__(self):
+ return PickleType, (self.protocol,
+ None,
+ self.mutable,
+ self.comparator)
+
def bind_processor(self, dialect):
impl_processor = self.impl.bind_processor(dialect)
dumps = self.pickler.dumps
return [self[key] for key in self._list]
def itervalues(self):
- return iter(self.values())
+ return iter([self[key] for key in self._list])
def keys(self):
return list(self._list)
@profiling.function_call_count(1194,
versions={'2.5':1191, '2.6':1191,
'2.6+cextension':1194,
- '2.4': 807}
+ '2.4': 763}
)
def go():
p2 = sess2.merge(p1)
def test_profile_1_create_tables(self):
self.test_baseline_1_create_tables()
- @profiling.function_call_count(5371, {'2.4': 3650})
+ @profiling.function_call_count(5045, {'2.4': 3650})
def test_profile_1a_populate(self):
self.test_baseline_1a_populate()
- @profiling.function_call_count(259, {'2.4': 186})
+ @profiling.function_call_count(245, {'2.4': 172})
def test_profile_2_insert(self):
self.test_baseline_2_insert()
- @profiling.function_call_count(3834, {'2.4': 2158})
+ @profiling.function_call_count(3634, {'2.4': 2158})
def test_profile_3_properties(self):
self.test_baseline_3_properties()
def test_profile_5_aggregates(self):
self.test_baseline_5_aggregates()
- @profiling.function_call_count(1904, {'2.4': 1193})
+ @profiling.function_call_count(1904, {'2.4': 1118})
def test_profile_6_editing(self):
self.test_baseline_6_editing()
- @profiling.function_call_count(2431, {'2.4': 1673, '2.6+cextension'
- : 2502})
+ @profiling.function_call_count(2598, {'2.4': 1673,
+ '2.7+cextension':2431,
+ '2.6+cextension': 2502})
def test_profile_7_multiview(self):
self.test_baseline_7_multiview()
@profiling.function_call_count(6783, {
'2.6': 7194,
'2.7': 7298,
- '2.7+cextension': 7288,
+ '2.7+cextension': 6894,
'2.6+cextension': 7184,
})
def test_profile_3_properties(self):
# and this number go down slightly when using the C extensions
- @profiling.function_call_count(22510, {'2.6': 24055, '2.7': 24214})
+ @profiling.function_call_count(22510, {'2.6': 24055, '2.7': 22921})
def test_profile_4_expressions(self):
self.test_baseline_4_expressions()