]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Can now call make_transient() on an instance that
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 15 Jun 2010 18:04:13 +0000 (14:04 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 15 Jun 2010 18:04:13 +0000 (14:04 -0400)
is referenced by parent objects via many-to-one,
without the parent's foreign key value getting
temporarily set to None - this was a function
of the "detect primary key switch" flush handler.
It now ignores objects that are no longer
in the "persistent" state, and the parent's
foreign key identifier is left unaffected.

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

diff --git a/CHANGES b/CHANGES
index 53c90278baf00dd916e07abde009021626a43e76..a479afa9a68b8025e949ec4bdb1631ad160342cf 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -20,6 +20,15 @@ CHANGES
     
   - Subquery-eager-loading now works with Query objects
     which include params(), as well as get() Queries.
+
+  - Can now call make_transient() on an instance that
+    is referenced by parent objects via many-to-one,
+    without the parent's foreign key value getting
+    temporarily set to None - this was a function
+    of the "detect primary key switch" flush handler.
+    It now ignores objects that are no longer 
+    in the "persistent" state, and the parent's 
+    foreign key identifier is left unaffected.
     
 - sql
   - The warning emitted by the Unicode and String types
index ba2ae8889c2371341c06d3906b6dbdaf0959ed0e..7a8c4cf702647f7becf4524f15ee123269a946a6 100644 (file)
@@ -776,7 +776,7 @@ class DetectKeySwitch(DependencyProcessor):
                                     uowcommit, self.passive_updates)
 
     def _pks_changed(self, uowcommit, state):
-        return sync.source_modified(uowcommit, 
+        return state.has_identity and sync.source_modified(uowcommit, 
                                     state, 
                                     self.mapper, 
                                     self.prop.synchronize_pairs)
index a352e3b34d5268b606601411286c37da8d428f85..b89456fda23bf34be4ce0a02992e38beb78dd69b 100644 (file)
@@ -2,14 +2,15 @@
 Primary key changing capabilities and passive/non-passive cascading updates.
 
 """
-from sqlalchemy.test.testing import eq_, assert_raises, assert_raises_message
+from sqlalchemy.test.testing import eq_, ne_, assert_raises, assert_raises_message
 import sqlalchemy as sa
 from sqlalchemy.test import testing
 from sqlalchemy import Integer, String, ForeignKey, Unicode
 from sqlalchemy.test.schema import Table, Column
 from sqlalchemy.orm import mapper, relationship, create_session, backref
+from sqlalchemy.orm.session import make_transient
 from sqlalchemy.test.testing import eq_
-from test.orm import _base
+from test.orm import _base, _fixtures
 
 class NaturalPKTest(_base.MappedTest):
 
@@ -149,11 +150,15 @@ class NaturalPKTest(_base.MappedTest):
         def go():
             sess.flush()
         if not passive_updates:
-            self.assert_sql_count(testing.db, go, 4) # test passive_updates=False; load addresses, update user, update 2 addresses
+            self.assert_sql_count(testing.db, go, 4) # test passive_updates=False; 
+                                                    #load addresses, update user, update 2 addresses
         else:
             self.assert_sql_count(testing.db, go, 1) # test passive_updates=True; update user
         sess.expunge_all()
-        assert User(username='jack', addresses=[Address(username='jack'), Address(username='jack')]) == sess.query(User).get('jack')
+        assert User(username='jack', addresses=[
+                                        Address(username='jack'), 
+                                        Address(username='jack')]) == \
+                            sess.query(User).get('jack')
 
         u1 = sess.query(User).get('jack')
         u1.addresses = []
@@ -363,6 +368,38 @@ class NaturalPKTest(_base.MappedTest):
         r = sess.query(Item).with_parent(u2).all()
         eq_(Item(itemname='item2'), r[0])
 
+class TransientExceptionTesst(_fixtures.FixtureTest):
+    run_inserts = None
+    
+    @testing.resolve_artifact_names
+    def test_transient_exception(self):
+        """An object that goes from a pk value to transient/pending
+        doesn't count as a "pk" switch.
+        
+        """
+        mapper(User, users)
+        mapper(Address, addresses, properties={'user':relationship(User)})
+        
+        sess = create_session()
+        u1 = User(id=5, name='u1')
+        ad1 = Address(email_address='e1', user=u1)
+        sess.add_all([u1, ad1])
+        sess.flush()
+        
+        make_transient(u1)
+        u1.id = None
+        u1.username='u2'
+        sess.add(u1)
+        sess.flush()
+        
+        eq_(ad1.user_id, 5)
+        
+        sess.expire_all()
+        eq_(ad1.user_id, 5)
+        ne_(u1.id, 5)
+        ne_(u1.id, None)
+        eq_(sess.query(User).count(), 2)
+        
 class ReversePKsTest(_base.MappedTest):
     """reverse the primary keys of two entities and ensure bookkeeping succeeds."""