]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
more polymorphic adjustments to circular dependency sort
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 29 May 2006 17:21:41 +0000 (17:21 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 29 May 2006 17:21:41 +0000 (17:21 +0000)
doc/build/content/dbengine.txt
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/unitofwork.py

index 2193ab6b5de0d14337e7f63c19688ac30c817c83..715e274fad008b6137869b4d59effdf98cc5a224 100644 (file)
@@ -192,7 +192,7 @@ To get at the actual `Connection` object which is used by implicit executions, c
     conn1 = db.contextual_connection()
     conn2 = db.contextual_connection()
 
-    >>> assert conn1 is conn2
+    >>> assert conn1.connection is conn2.connection
     True
 
 When the `plain` strategy is used, the `contextual_connection()` method is synonymous with the `connect()` method; both return a distinct connection from the pool.
index 07e4f503d3c0f9d4ae30bd948f95e23bbde5fde0..11806ea8f58d8c69639143e8f91e14217c042437 100644 (file)
@@ -231,7 +231,7 @@ class Mapper(object):
             if self.columntoproperty.has_key(column):
                 continue
             if not self.columns.has_key(column.key):
-                self.columns[column.key] = column
+                self.columns[column.key] = self.select_table.corresponding_column(column, keys_ok=True, raiseerr=True)
 
             prop = self.props.get(column.key, None)
             if prop is None:
@@ -291,7 +291,11 @@ class Mapper(object):
             return self.inherits.base_mapper()
         else:
             return self
-            
+    
+    def _inherits(self, mapper):
+        """returns True if the given mapper and this mapper are in the same inheritance hierarchy"""
+        return self.base_mapper() is mapper.base_mapper()
+        
     def add_polymorphic_mapping(self, key, class_or_mapper, entity_name=None):
         if isinstance(class_or_mapper, type):
             class_or_mapper = class_mapper(class_or_mapper, entity_name=entity_name)
@@ -338,7 +342,7 @@ class Mapper(object):
         self.props[key] = prop
 
         if isinstance(prop, ColumnProperty):
-            self.columns[key] = prop.columns[0]
+            self.columns[key] = self.select_table.corresponding_column(prop.columns[0], keys_ok=True, raiseerr=True)
             for col in prop.columns:
                 proplist = self.columntoproperty.setdefault(col, [])
                 proplist.append(prop)
index 9f8883a3106a73be9223c2eaf255d000d98106c3..8c38b897fef3afcb1c56bc7f29e920ad141ac839 100644 (file)
@@ -150,12 +150,9 @@ class PropertyLoader(mapper.MapperProperty):
 
     private = property(lambda s:s.cascade.delete_orphan)
     
-    def cascade_iterator(self, type, object, recursive=None):
+    def cascade_iterator(self, type, object, recursive):
         if not type in self.cascade:
             return
-        if recursive is None:
-            recursive = sets.Set()
-            
         childlist = sessionlib.global_attributes.get_history(object, self.key, passive=True)
             
         for c in childlist.added_items() + childlist.deleted_items() + childlist.unchanged_items():
@@ -163,7 +160,7 @@ class PropertyLoader(mapper.MapperProperty):
                 if c not in recursive:
                     recursive.add(c)
                     yield c
-                    for c2 in self.mapper.cascade_iterator(type, c, recursive):
+                    for c2 in self.mapper.primary_mapper().cascade_iterator(type, c, recursive):
                         yield c2
 
     def copy(self):
@@ -247,10 +244,9 @@ class PropertyLoader(mapper.MapperProperty):
         
     def _get_direction(self):
         """determines our 'direction', i.e. do we represent one to many, many to many, etc."""
-        
         if self.secondaryjoin is not None:
             return sync.MANYTOMANY
-        elif self.parent.mapped_table is self.target:
+        elif self.parent.mapped_table is self.target or self.parent.select_table is self.target:
             if self.foreignkey.primary_key:
                 return sync.MANYTOONE
             else:
index 1ebf9cd6981c132ac7b65b96d108b0de37c26fb3..3927b949e851a05c152f0f211aaf2e2e164e4c0a 100644 (file)
@@ -761,8 +761,9 @@ class UOWTask(object):
                 for dep in task.dependencies:
                     if not dependency_in_cycles(dep):
                         extradeplist.append(dep)
-                    l = deps_by_targettask.setdefault(dep.targettask, [])
-                    l.append(dep)
+                    for t in dep.targettask.polymorphic_tasks():
+                        l = deps_by_targettask.setdefault(t, [])
+                        l.append(dep)
 
         for t in cycles:
             for task in t.polymorphic_tasks():
@@ -771,8 +772,10 @@ class UOWTask(object):
                     object_to_original_task[obj] = task
                     #print "OBJ", repr(obj), "TASK", repr(task)
                 
+                    
                     for dep in deps_by_targettask.get(task, []):
                         # is this dependency involved in one of the cycles ?
+                        #print "DEP iterate", dep.processor.key    
                         if not dependency_in_cycles(dep):
                             continue
                         #print "DEP", dep.processor.key    
@@ -790,8 +793,9 @@ class UOWTask(object):
                         for o in childlist:
                             if o is None or not childtask.contains_object(o, polymorphic=True):
                                 continue
-                            #print "CHILD", o
+                            #print "parent/child", obj, o
                             whosdep = dep.whose_dependent_on_who(obj, o)
+                            #print "WHOSEDEP", dep.processor.key, dep.processor.direction, whosdep
                             if whosdep is not None:
                                 tuples.append(whosdep)
                                 # create a UOWDependencyProcessor representing this pair of objects.
@@ -820,13 +824,17 @@ class UOWTask(object):
 
         def make_task_tree(node, parenttask):
             """takes a dependency-sorted tree of objects and creates a tree of UOWTasks"""
-            #print "MAKETASKTREE", node.item
+            #print "MAKETASKTREE", node.item, parenttask
 
             t = get_object_task(node.item)
             for n in node.children:
                 t2 = make_task_tree(n, t)
-                    
-            can_add_to_parent = t.mapper is parenttask.mapper
+            
+            # this flag is attempting to coalesce non-dependent operations into lists, instead of
+            # individual tasks, to produce more of a "batching" effect.  great when it works,
+            # but easily breakable...so its at False for now
+            can_add_to_parent = False #parenttask.mapper._inherits(t.mapper)
+            
             original_task = object_to_original_task[node.item]
             #print "ORIG TASK", original_task
             if original_task.contains_object(node.item, polymorphic=False):