]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
fix bug + add coverage to ensure unneeded SaveUpdateAll/DeleteAll plus extra
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 9 Apr 2010 22:04:18 +0000 (18:04 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 9 Apr 2010 22:04:18 +0000 (18:04 -0400)
work doesn't occur during per-state usage

lib/sqlalchemy/orm/dependency.py
lib/sqlalchemy/orm/unitofwork.py
test/orm/test_unitofworkv2.py

index faff4c4aa8416a354b5de845b4263acae84eb167..bab3cb936b57c7daf3e28ca934e4c3818cf16ead 100644 (file)
@@ -117,7 +117,6 @@ class DependencyProcessor(object):
         # assertions to ensure this method isn't being
         # called unnecessarily.  can comment these out when 
         # code is stable
-        #assert ('has_flush_activity', self) in uow.attributes
         assert not self.post_update or not self._check_reverse(uow)
         
 
index 163adff1416cac618ee6707e01a5ee2c5c85416c..1c1b93c472bed85122dae71c8aa52d2b2590a3f6 100644 (file)
@@ -80,8 +80,9 @@ class UOWTransaction(object):
         self.attributes = {}
         
         # dictionary of mappers to sets of 
-        # DependencyProcessors which have that mapper
-        # as a parent.
+        # DependencyProcessors, which are also 
+        # set to be part of the sorted flush actions,
+        # which have that mapper as a parent.
         self.deps = util.defaultdict(set)
         
         # dictionary of mappers to sets of InstanceState
@@ -151,7 +152,6 @@ class UOWTransaction(object):
     
     def register_preprocessor(self, processor, fromparent):
         self.presort_actions.add(Preprocess(processor, fromparent))
-        self.deps[processor.parent.base_mapper].add(processor)
             
     def register_object(self, state, isdelete=False, listonly=False):
         if not self.session._contains_state(state):
@@ -248,8 +248,8 @@ class UOWTransaction(object):
         #sort = topological.sort(self.dependencies, postsort_actions)
         #print "--------------"
         #print self.dependencies
-        #print postsort_actions
-        #print "COUNT OF POSTSORT ACTIONS", len(postsort_actions)
+        print postsort_actions
+        print "COUNT OF POSTSORT ACTIONS", len(postsort_actions)
         
         # execute
         if self.cycles:
@@ -360,6 +360,7 @@ class ProcessAll(IterateMappersMixin, PostSortRec):
         self.dependency_processor = dependency_processor
         self.delete = delete
         self.fromparent = fromparent
+        uow.deps[dependency_processor.parent.base_mapper].add(dependency_processor)
         
     def execute(self, uow):
         states = self._elements(uow)
index 201b0ad94ebef9b15e415fdaa87ecee7511aecaa..7fef87d33cd6630d4679a6c6b0a90b532dfc58e6 100644 (file)
@@ -13,9 +13,7 @@ from test.orm._fixtures import keywords, addresses, Base, Keyword,  \
             order_items, Item, Order, Node, \
             composite_pk_table, CompositePk
 
-class UOWTest(_fixtures.FixtureTest, testing.AssertsExecutionResults):
-    run_inserts = None
-
+class AssertsUOW(object):
     def _assert_uow_size(self,
         session, 
         expected
@@ -31,6 +29,10 @@ class UOWTest(_fixtures.FixtureTest, testing.AssertsExecutionResults):
         postsort_actions = uow._generate_actions()
         print postsort_actions
         eq_(len(postsort_actions), expected, postsort_actions)
+
+class UOWTest(_fixtures.FixtureTest, testing.AssertsExecutionResults, AssertsUOW):
+    run_inserts = None
+
     
 
 class RudimentaryFlushTest(UOWTest):
@@ -223,7 +225,7 @@ class RudimentaryFlushTest(UOWTest):
         u1 = User(name='ed')
         sess.add(u1)
         self._assert_uow_size(sess, 2)
-        
+
     def test_o2m_flush_size(self):
         mapper(User, users, properties={
             'addresses':relationship(Address),
@@ -488,7 +490,50 @@ class SingleCycleTest(UOWTest):
         n1.children
         self._assert_uow_size(sess, 2)
 
-class SingleCycleM2MTest(_base.MappedTest, testing.AssertsExecutionResults):
+class SingleCyclePlusAttributeTest(_base.MappedTest, testing.AssertsExecutionResults, AssertsUOW):
+    @classmethod
+    def define_tables(cls, metadata):
+        Table('nodes', metadata,
+            Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
+            Column('parent_id', Integer, ForeignKey('nodes.id')),
+            Column('data', String(30))
+        )
+        
+        Table('foobars', metadata,
+            Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
+            Column('parent_id', Integer, ForeignKey('nodes.id')),
+        )
+
+    @testing.resolve_artifact_names
+    def test_flush_size(self):
+        class Node(Base):
+            pass
+        class FooBar(Base):
+            pass
+
+        mapper(Node, nodes, properties={
+            'children':relationship(Node),
+            'foobars':relationship(FooBar)
+        })
+        mapper(FooBar, foobars)
+
+        sess = create_session()
+        n1 = Node(data='n1')
+        n2 = Node(data='n2')
+        n1.children.append(n2)
+        sess.add(n1)
+        # ensure "foobars" doesn't get yanked in here
+        self._assert_uow_size(sess, 3)
+        
+        n1.foobars.append(FooBar())
+        # saveupdateall/deleteall for FooBar added here,
+        # plus processstate node.foobars 
+        # currently the "all" procs stay in pairs
+        self._assert_uow_size(sess, 6)
+        
+        sess.flush()
+
+class SingleCycleM2MTest(_base.MappedTest, testing.AssertsExecutionResults, AssertsUOW):
 
     @classmethod
     def define_tables(cls, metadata):
@@ -635,5 +680,4 @@ class SingleCycleM2MTest(_base.MappedTest, testing.AssertsExecutionResults):
                 lambda ctx:[{'id': n2.id}, {'id': n3.id}]
             ),
         )
-        
-        
+