]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
fixed up some debug logging to be conditional, adds speed. made some
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 4 Dec 2006 21:17:05 +0000 (21:17 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 4 Dec 2006 21:17:05 +0000 (21:17 +0000)
attribute-related lambdas more direct.

CHANGES
lib/sqlalchemy/orm/attributes.py
lib/sqlalchemy/orm/strategies.py
lib/sqlalchemy/orm/unitofwork.py

diff --git a/CHANGES b/CHANGES
index 8e013d73a87df4afa08020dc285cc9d277d702b9..45caad577267db0ccac0e0eb06b5cc4d08ae3ef5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,10 +1,13 @@
 0.3.2
+- major speed enhancements vs. 0.3.1 
+  - made conditional dozens of debug log calls that were 
+  time-intensive to generate log messages
+  - fixed bug in cascade rules whereby the entire object graph
+  could be unnecessarily cascaded on the save/update cascade
 - added keywords for EXCEPT, INTERSECT, EXCEPT ALL, INTERSECT ALL
 [ticket:247]
 - added label() function to Select class, when scalar=True is used
 to create a scalar subquery.
-- added extra check to "stop" cascading on save/update/save-update if
-an instance is detected to be already in the session.
 - fix to session.update() to preserve "dirty" status of incoming object
 - sending a selectable to an IN no longer creates a "union" out of multiple
 selects; only one selectable to an IN is allowed now (make a union yourself
index f7fb98673ebcffbccab87c59a9d21137d7427916..915ccd209fcac21bedfe7951604c3451a1f01708 100644 (file)
@@ -25,17 +25,17 @@ class InstrumentedAttribute(object):
         self.mutable_scalars = mutable_scalars
         if copy_function is None:
             if uselist:
-                self._copyfunc = lambda x: [y for y in x]
+                self.copy = lambda x:[y for y in x]
             else:
                 # scalar values are assumed to be immutable unless a copy function
                 # is passed
-                self._copyfunc = lambda x: x
+                self.copy = lambda x:x
         else:
-            self._copyfunc = copy_function
+            self.copy = lambda x:copy_function(x)
         if compare_function is None:
-            self._compare_function = lambda x,y: x == y
+            self.is_equal = lambda x,y: x == y
         else:
-            self._compare_function = compare_function
+            self.is_equal = compare_function
         self.extensions = util.to_list(extension or [])
 
     def __set__(self, obj, value):
@@ -47,11 +47,6 @@ class InstrumentedAttribute(object):
             return self
         return self.get(obj)
 
-    def is_equal(self, x, y):
-        return self._compare_function(x, y)
-    def copy(self, value):
-        return self._copyfunc(value)
-    
     def check_mutable_modified(self, obj):
         if self.mutable_scalars:
             h = self.get_history(obj, passive=True)
index a3a92841de07a7e5d0ab03fa9501346493ab35f6..82234c34a8fd7e32f0864770d4f735a15d499958 100644 (file)
@@ -18,6 +18,8 @@ class ColumnLoader(LoaderStrategy):
     def init(self):
         super(ColumnLoader, self).init()
         self.columns = self.parent_property.columns
+        self._should_log_debug = logging.is_debug_enabled(self.logger)
+        
     def setup_query(self, context, eagertable=None, **kwargs):
         for c in self.columns:
             if eagertable is not None:
@@ -27,11 +29,13 @@ class ColumnLoader(LoaderStrategy):
 
     def init_class_attribute(self):
         self.logger.info("register managed attribute %s on class %s" % (self.key, self.parent.class_.__name__))
-        sessionlib.attribute_manager.register_attribute(self.parent.class_, self.key, uselist=False, copy_function=lambda x: self.columns[0].type.copy_value(x), compare_function=lambda x,y:self.columns[0].type.compare_values(x,y), mutable_scalars=self.columns[0].type.is_mutable())
+        coltype = self.columns[0].type
+        sessionlib.attribute_manager.register_attribute(self.parent.class_, self.key, uselist=False, copy_function=coltype.copy_value, compare_function=coltype.compare_values, mutable_scalars=self.columns[0].type.is_mutable())
 
     def process_row(self, selectcontext, instance, row, identitykey, isnew):
         if isnew:
-            self.logger.debug("populating %s with %s/%s" % (mapperutil.attribute_str(instance, self.key), row.__class__.__name__, self.columns[0].key))
+            if self._should_log_debug:
+                self.logger.debug("populating %s with %s/%s" % (mapperutil.attribute_str(instance, self.key), row.__class__.__name__, self.columns[0].key))
             instance.__dict__[self.key] = row[self.columns[0]]
         
 ColumnLoader.logger = logging.class_logger(ColumnLoader)
@@ -43,6 +47,7 @@ class DeferredColumnLoader(LoaderStrategy):
         super(DeferredColumnLoader, self).init()
         self.columns = self.parent_property.columns
         self.group = self.parent_property.group
+        self._should_log_debug = logging.is_debug_enabled(self.logger)
 
     def init_class_attribute(self):
         self.logger.info("register managed attribute %s on class %s" % (self.key, self.parent.class_.__name__))
@@ -66,7 +71,8 @@ class DeferredColumnLoader(LoaderStrategy):
             if prop is not self.parent_property:
                 return prop._get_strategy(DeferredColumnLoader).setup_loader(instance)
         def lazyload():
-            self.logger.debug("deferred load %s group %s" % (mapperutil.attribute_str(instance, self.key), str(self.group)))
+            if self._should_log_debug:
+                self.logger.debug("deferred load %s group %s" % (mapperutil.attribute_str(instance, self.key), str(self.group)))
             try:
                 pk = self.parent.pks_by_table[self.columns[0].table]
             except KeyError:
@@ -130,6 +136,7 @@ class AbstractRelationLoader(LoaderStrategy):
         self.attributeext = self.parent_property.attributeext
         self.order_by = self.parent_property.order_by
         self.remote_side = self.parent_property.remote_side
+        self._should_log_debug = logging.is_debug_enabled(self.logger)
         
     def _init_instance_attribute(self, instance, callable_=None):
         return sessionlib.attribute_manager.init_instance_attribute(instance, self.key, self.uselist, cascade=self.cascade,  trackparent=True, callable_=callable_)
@@ -144,7 +151,8 @@ class NoLoader(AbstractRelationLoader):
     def process_row(self, selectcontext, instance, row, identitykey, isnew):
         if isnew:
             if not self.is_default or len(selectcontext.options):
-                self.logger.debug("set instance-level no loader on %s" % mapperutil.attribute_str(instance, self.key))
+                if self._should_log_debug:
+                    self.logger.debug("set instance-level no loader on %s" % mapperutil.attribute_str(instance, self.key))
                 self._init_instance_attribute(instance)
 
 NoLoader.logger = logging.class_logger(NoLoader)
@@ -297,7 +305,7 @@ class EagerLoader(AbstractRelationLoader):
 
         self.clauses = {}
         self.clauses_by_lead_mapper = {}
-        self.__should_log_debug = logging.is_debug_enabled(self.logger)
+
     class AliasedClauses(object):
         """defines a set of join conditions and table aliases which are aliased on a randomly-generated
         alias name, corresponding to the connection of an optional parent AliasedClauses object and a 
@@ -480,7 +488,7 @@ class EagerLoader(AbstractRelationLoader):
             identity_key = self.mapper.identity_key_from_row(decorated_row)
         except KeyError:
             # else degrade to a lazy loader
-            if self.__should_log_debug:
+            if self._should_log_debug:
                 self.logger.debug("degrade to lazy loader on %s" % mapperutil.attribute_str(instance, self.key))
             self.parent_property._get_strategy(LazyLoader).process_row(selectcontext, instance, row, identitykey, isnew)
             return
@@ -490,7 +498,7 @@ class EagerLoader(AbstractRelationLoader):
         selectcontext.recursion_stack.add(self)
         try:
             if not self.uselist:
-                if self.__should_log_debug:
+                if self._should_log_debug:
                     self.logger.debug("eagerload scalar instance on %s" % mapperutil.attribute_str(instance, self.key))
                 if isnew:
                     # set a scalar object instance directly on the parent object, 
@@ -502,7 +510,7 @@ class EagerLoader(AbstractRelationLoader):
                     self.mapper._instance(selectcontext, decorated_row, None)
             else:
                 if isnew:
-                    if self.__should_log_debug:
+                    if self._should_log_debug:
                         self.logger.debug("initialize UniqueAppender on %s" % mapperutil.attribute_str(instance, self.key))
                     # call the SmartProperty's initialize() method to create a new, blank list
                     l = getattr(instance.__class__, self.key).initialize(instance)
@@ -513,7 +521,7 @@ class EagerLoader(AbstractRelationLoader):
                     # store it in the "scratch" area, which is local to this load operation.
                     selectcontext.attributes[(instance, self.key)] = appender
                 result_list = selectcontext.attributes[(instance, self.key)]
-                if self.__should_log_debug:
+                if self._should_log_debug:
                     self.logger.debug("eagerload list instance on %s" % mapperutil.attribute_str(instance, self.key))
                 self.mapper._instance(selectcontext, decorated_row, result_list)
         finally:
index 4ecf8b4a046da47b6c61594d61e3e2f169f4de08..3c1238287bf1b2a935ab77429964c8e83f0f40b5 100644 (file)
@@ -116,17 +116,13 @@ class UnitOfWork(object):
         attribute_manager.set_callable(obj, key, func, uselist, **kwargs)
     
     def register_clean(self, obj):
-        try:
+        if obj in self.new:
             self.new.remove(obj)
-        except KeyError:
-            pass
         if not hasattr(obj, '_instance_key'):
             mapper = object_mapper(obj)
             obj._instance_key = mapper.instance_key(obj)
-        try:
+        if hasattr(obj, '_sa_insert_order'):
             delattr(obj, '_sa_insert_order')
-        except AttributeError:
-            pass
         self.identity_map[obj._instance_key] = obj
         attribute_manager.commit(obj)