diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-12-04 11:52:16 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-12-04 11:52:16 -0500 |
| commit | 3ec9b9f6b601b8ef69d4978c7182e8efedefd191 (patch) | |
| tree | fded91038e426b974d141f2a4e4be714a18d0ae2 /test/orm | |
| parent | 935bc34dc50d5e4bdf181a8287d6e4cdbde073d0 (diff) | |
| download | sqlalchemy-3ec9b9f6b601b8ef69d4978c7182e8efedefd191.tar.gz | |
- The :meth:`.Session.merge` method now tracks pending objects by
primary key before emitting an INSERT, and merges distinct objects with
duplicate primary keys together as they are encountered, which is
essentially semi-deterministic at best. This behavior
matches what happens already with persistent objects.
fixes #3601
Diffstat (limited to 'test/orm')
| -rw-r--r-- | test/orm/test_merge.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/test/orm/test_merge.py b/test/orm/test_merge.py index a52274896..dab9f4305 100644 --- a/test/orm/test_merge.py +++ b/test/orm/test_merge.py @@ -1102,6 +1102,101 @@ class MergeTest(_fixtures.FixtureTest): eq_(ustate.load_path.path, (umapper, )) eq_(ustate.load_options, set([opt2])) + def test_resolve_conflicts_pending_doesnt_interfere_no_ident(self): + User, Address, Order = ( + self.classes.User, self.classes.Address, self.classes.Order) + users, addresses, orders = ( + self.tables.users, self.tables.addresses, self.tables.orders) + + mapper(User, users, properties={ + 'orders': relationship(Order) + }) + mapper(Order, orders, properties={ + 'address': relationship(Address) + }) + mapper(Address, addresses) + + u1 = User(id=7, name='x') + u1.orders = [ + Order(description='o1', address=Address(email_address='a')), + Order(description='o2', address=Address(email_address='b')), + Order(description='o3', address=Address(email_address='c')) + ] + + sess = Session() + sess.merge(u1) + sess.flush() + + eq_( + sess.query(Address.email_address).order_by( + Address.email_address).all(), + [('a', ), ('b', ), ('c', )] + ) + + def test_resolve_conflicts_pending(self): + User, Address, Order = ( + self.classes.User, self.classes.Address, self.classes.Order) + users, addresses, orders = ( + self.tables.users, self.tables.addresses, self.tables.orders) + + mapper(User, users, properties={ + 'orders': relationship(Order) + }) + mapper(Order, orders, properties={ + 'address': relationship(Address) + }) + mapper(Address, addresses) + + u1 = User(id=7, name='x') + u1.orders = [ + Order(description='o1', address=Address(id=1, email_address='a')), + Order(description='o2', address=Address(id=1, email_address='b')), + Order(description='o3', address=Address(id=1, email_address='c')) + ] + + sess = Session() + sess.merge(u1) + sess.flush() + + eq_( + sess.query(Address).one(), + Address(id=1, email_address='c') + ) + + def test_resolve_conflicts_persistent(self): + User, Address, Order = ( + self.classes.User, self.classes.Address, self.classes.Order) + users, addresses, orders = ( + self.tables.users, self.tables.addresses, self.tables.orders) + + mapper(User, users, properties={ + 'orders': relationship(Order) + }) + mapper(Order, orders, properties={ + 'address': relationship(Address) + }) + mapper(Address, addresses) + + sess = Session() + sess.add(Address(id=1, email_address='z')) + sess.commit() + + u1 = User(id=7, name='x') + u1.orders = [ + Order(description='o1', address=Address(id=1, email_address='a')), + Order(description='o2', address=Address(id=1, email_address='b')), + Order(description='o3', address=Address(id=1, email_address='c')) + ] + + sess = Session() + sess.merge(u1) + sess.flush() + + eq_( + sess.query(Address).one(), + Address(id=1, email_address='c') + ) + class M2ONoUseGetLoadingTest(fixtures.MappedTest): """Merge a one-to-many. The many-to-one on the other side is set up |
