From 0264fea0505aa65bcb4d3d9795177859b1969b72 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ga=C3=ABtan=20de=20Menten?= Date: Fri, 19 Sep 2008 07:11:46 +0000 Subject: [PATCH] Get a bit more speed into the new _sort_states function. It's probably possible to get even more speed by getting rid of the decorator and call the method directly, but it makes for slightly less readable code so I won't do it since I don't know whether this code is speed-critical or not. --- lib/sqlalchemy/orm/attributes.py | 36 ++++++++++++++++---------------- lib/sqlalchemy/orm/mapper.py | 23 ++++++++++---------- lib/sqlalchemy/orm/uowdumper.py | 2 +- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 296c019a7f..79e5d22f7b 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -197,8 +197,8 @@ def proxied_attribute_factory(descriptor): class AttributeImpl(object): """internal implementation for instrumented attributes.""" - def __init__(self, class_, key, - callable_, class_manager, trackparent=False, extension=None, + def __init__(self, class_, key, + callable_, class_manager, trackparent=False, extension=None, compare_function=None, active_history=False, **kwargs): """Construct an AttributeImpl. @@ -219,13 +219,13 @@ class AttributeImpl(object): to it via this attribute. extension - a single or list of AttributeExtension object(s) which will + a single or list of AttributeExtension object(s) which will receive set/delete/append/remove/etc. events. compare_function a function that compares two values which are normally assignable to this attribute. - + active_history indicates that get_history() should always return the "old" value, even if it means executing a lazy callable upon attribute change. @@ -399,7 +399,7 @@ class ScalarAttributeImpl(AttributeImpl): old = self.get(state) else: old = state.dict.get(self.key, NO_VALUE) - + state.modified_event(self, False, old) if self.extensions: @@ -429,10 +429,10 @@ class MutableScalarAttributeImpl(ScalarAttributeImpl): uses_objects = False - def __init__(self, class_, key, callable_, - class_manager, copy_function=None, + def __init__(self, class_, key, callable_, + class_manager, copy_function=None, compare_function=None, **kwargs): - super(ScalarAttributeImpl, self).__init__(class_, key, callable_, + super(ScalarAttributeImpl, self).__init__(class_, key, callable_, class_manager, compare_function=compare_function, **kwargs) class_manager.mutable_attributes.add(key) if copy_function is None: @@ -473,8 +473,8 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl): accepts_scalar_loader = False uses_objects = True - def __init__(self, class_, key, callable_, class_manager, - trackparent=False, extension=None, copy_function=None, + def __init__(self, class_, key, callable_, class_manager, + trackparent=False, extension=None, copy_function=None, compare_function=None, **kwargs): super(ScalarObjectAttributeImpl, self).__init__(class_, key, callable_, class_manager, trackparent=trackparent, extension=extension, @@ -550,8 +550,8 @@ class CollectionAttributeImpl(AttributeImpl): accepts_scalar_loader = False uses_objects = True - def __init__(self, class_, key, callable_, class_manager, - typecallable=None, trackparent=False, extension=None, + def __init__(self, class_, key, callable_, class_manager, + typecallable=None, trackparent=False, extension=None, copy_function=None, compare_function=None, **kwargs): super(CollectionAttributeImpl, self).__init__(class_, key, callable_, class_manager, trackparent=trackparent, @@ -761,12 +761,12 @@ class GenericBackrefExtension(interfaces.AttributeExtension): new_state = instance_state(child) new_state.get_impl(self.key).append(new_state, state.obj(), initiator, passive=True) return child - + def append(self, state, child, initiator): child_state = instance_state(child) child_state.get_impl(self.key).append(child_state, state.obj(), initiator, passive=True) return child - + def remove(self, state, child, initiator): if child is not None: child_state = instance_state(child) @@ -782,7 +782,7 @@ class InstanceState(object): runid = None expired_attributes = EMPTY_SET insert_order = None - + def __init__(self, obj, manager): self.class_ = obj.__class__ self.manager = manager @@ -801,7 +801,7 @@ class InstanceState(object): @property def sort_key(self): return self.key and self.key[1] or self.insert_order - + def check_modified(self): if self.modified: return True @@ -1443,8 +1443,8 @@ def unregister_class(class_): manager.instantiable = False manager.unregister() -def register_attribute(class_, key, uselist, useobject, - callable_=None, proxy_property=None, +def register_attribute(class_, key, uselist, useobject, + callable_=None, proxy_property=None, mutable_scalars=False, impl_class=None, **kwargs): manager = manager_of_class(class_) if manager.is_instrumented(key): diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index e79cd47cb7..63521280d3 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -16,6 +16,7 @@ available in [sqlalchemy.orm#]. import types import weakref +import operator from itertools import chain from sqlalchemy import sql, util, log @@ -545,7 +546,7 @@ class Mapper(object): # determine primary key from argument or mapped_table pks - reduce to the minimal set of columns if self.primary_key_argument: primary_key = sqlutil.reduce_columns( - [self.mapped_table.corresponding_column(c) for c in self.primary_key_argument], + [self.mapped_table.corresponding_column(c) for c in self.primary_key_argument], ignore_nonexistent_tables=True) else: primary_key = sqlutil.reduce_columns( @@ -640,7 +641,7 @@ class Mapper(object): def _is_userland_descriptor(self, obj): return not isinstance(obj, (MapperProperty, attributes.InstrumentedAttribute)) and hasattr(obj, '__get__') - + def _should_exclude(self, name, local): """determine whether a particular property should be implicitly present on the class. @@ -875,7 +876,7 @@ class Mapper(object): elif hasattr(method, '__sa_validators__'): for name in method.__sa_validators__: self._validators[name] = method - + if 'reconstruct_instance' in self.extension.methods: def reconstruct(instance): self.extension.reconstruct_instance(self, instance) @@ -1027,7 +1028,7 @@ class Mapper(object): def _get_committed_state_attr_by_column(self, state, column, passive=False): return self._get_col_to_prop(column).getcommitted(state, column, passive=passive) - + def _save_obj(self, states, uowtransaction, postupdate=False, post_update_cols=None, single=False): """Issue ``INSERT`` and/or ``UPDATE`` statements for a list of objects. @@ -1218,7 +1219,7 @@ class Mapper(object): for m in mapper.iterate_to_root(): if m.__inherits_equated_pairs: sync.populate(state, m, state, m, m.__inherits_equated_pairs) - + # testlib.pragma exempt:__hash__ inserted_objects.add((state, connection)) @@ -1637,20 +1638,20 @@ def reconstructor(fn): def validates(*names): """Decorate a method as a 'validator' for one or more named properties. - - Designates a method as a validator, a method which receives the + + Designates a method as a validator, a method which receives the name of the attribute as well as a value to be assigned, or in the - case of a collection to be added to the collection. The function + case of a collection to be added to the collection. The function can then raise validation exceptions to halt the process from continuing, or can modify or replace the value before proceeding. The function should otherwise return the given value. - + """ def wrap(fn): fn.__sa_validators__ = names return fn return wrap - + def _event_on_init(state, instance, args, kwargs): """Trigger mapper compilation and run init_instance hooks.""" @@ -1674,7 +1675,7 @@ def _event_on_init_failure(state, instance, args, kwargs): state.manager.events.original_init, instance, args, kwargs) def _sort_states(states): - return sorted(states, lambda a, b:cmp(a.sort_key, b.sort_key)) + return sorted(states, key=operator.attrgetter('sort_key')) def _load_scalar_attributes(state, attribute_names): mapper = _state_mapper(state) diff --git a/lib/sqlalchemy/orm/uowdumper.py b/lib/sqlalchemy/orm/uowdumper.py index 9ae7073b9f..17978b8c3d 100644 --- a/lib/sqlalchemy/orm/uowdumper.py +++ b/lib/sqlalchemy/orm/uowdumper.py @@ -45,7 +45,7 @@ class UOWDumper(unitofwork.UOWExecutor): def save_objects(self, trans, task): - for rec in sorted(task.polymorphic_tosave_elements, lambda a, b:cmp(a.state.sort_key, b.state.sort_key)): + for rec in sorted(task.polymorphic_tosave_elements, key=lambda a: a.state.sort_key): if rec.listonly: continue self.buf.write(self._indent()[:-1] + "+-" + self._repr_task_element(rec) + "\n") -- 2.47.3