]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- A tweak to the unit of work causes it to order
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 6 Mar 2011 20:37:18 +0000 (15:37 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 6 Mar 2011 20:37:18 +0000 (15:37 -0500)
the flush along relationship() dependencies even if
the given objects don't have any inter-attribute
references in memory, which was the behavior in
0.5 and earlier, so a flush of Parent/Child with
only foreign key/primary key set will succeed.
This while still maintaining 0.6 and above's not
generating a ton of useless internal dependency
structures within the flush that don't correspond
to state actually within the current flush.
[ticket:2082]

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

diff --git a/CHANGES b/CHANGES
index 907bc4a03a72d1fe62ba7ca5c24450667f6497df..02dc1cbac2024bd6be86e7145aa3533d6caa0663 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -17,6 +17,18 @@ CHANGES
     acquire the full list of objects in a single values() 
     call. [ticket:2087]
 
+  - A tweak to the unit of work causes it to order
+    the flush along relationship() dependencies even if 
+    the given objects don't have any inter-attribute 
+    references in memory, which was the behavior in 
+    0.5 and earlier, so a flush of Parent/Child with
+    only foreign key/primary key set will succeed.  
+    This while still maintaining 0.6 and above's not 
+    generating a ton of useless internal dependency 
+    structures within the flush that don't correspond 
+    to state actually within the current flush.
+    [ticket:2082]
+
 - sql
   - Added a fully descriptive error message for the
     case where Column is subclassed and _make_proxy()
index 402d031c3179590077b63bc4db0088c9367f98a4..338ecfb55e54e66eade91cd26597ab761016ff29 100644 (file)
@@ -242,7 +242,9 @@ class DependencyProcessor(object):
             if history and not history.empty():
                 return True
         else:
-            return False
+            return states and \
+                not self.prop._is_self_referential() and \
+                self.mapper in uowcommit.mappers
 
     def _verify_canload(self, state):
         if state is not None and \
index 20b643b4de36b9f865dd68d4aeba4c230e9f0f56..4063ccfabc67e3a81f61a3930357a349ad9e9de4 100644 (file)
@@ -400,6 +400,77 @@ class RudimentaryFlushTest(UOWTest):
             ),
         )
 
+    def test_natural_ordering(self):
+        """test that unconnected items take relationship() into account regardless."""
+
+        mapper(User, users)
+        mapper(Address, addresses, properties={
+            'parent':relationship(User)
+        })
+
+        sess = create_session()
+
+        u1 = User(id=1, name='u1')
+        a1 = Address(id=1, user_id=1, email_address='a2')
+
+        sess.add_all([u1, a1])
+        self.assert_sql_execution(
+            testing.db,
+            sess.flush,
+            CompiledSQL(
+                "INSERT INTO users (id, name) VALUES (:id, :name)", 
+                {'id':1, 'name':'u1'}),
+            CompiledSQL(
+                "INSERT INTO addresses (id, user_id, email_address) "
+                "VALUES (:id, :user_id, :email_address)",
+                {'email_address': 'a2', 'user_id': 1, 'id': 1}
+            )
+        )
+
+        sess.delete(u1)
+        sess.delete(a1)
+        self.assert_sql_execution(
+            testing.db,
+            sess.flush,
+            CompiledSQL(
+                "DELETE FROM addresses WHERE addresses.id = :id",
+                [{'id': 1}]
+            ),
+            CompiledSQL(
+                "DELETE FROM users WHERE users.id = :id",
+                [{'id': 1}]
+            )
+        )
+
+    def test_natural_selfref(self):
+        """test that unconnected items take relationship() into account regardless."""
+
+        mapper(Node, nodes, properties={
+            'children':relationship(Node)
+        })
+
+        sess = create_session()
+
+        n1 = Node(id=1)
+        n2 = Node(id=2, parent_id=1)
+        n3 = Node(id=3, parent_id=2)
+
+        # insert order is determined from add order since they
+        # are the same class
+        sess.add_all([n1, n2, n3])
+
+        self.assert_sql_execution(
+            testing.db,
+            sess.flush,
+            CompiledSQL(
+                "INSERT INTO nodes (id, parent_id, data) VALUES "
+                "(:id, :parent_id, :data)", 
+                [{'parent_id': None, 'data': None, 'id': 1}, 
+                {'parent_id': 1, 'data': None, 'id': 2}, 
+                {'parent_id': 2, 'data': None, 'id': 3}]
+                ),
+        )
+
     def test_many_to_many(self):
         mapper(Item, items, properties={
             'keywords':relationship(Keyword, secondary=item_keywords)