From: Jason Kirtland Date: Thu, 11 Feb 2010 00:43:34 +0000 (+0000) Subject: Fixed bug in session.merge() blocking dict-like collections from merging. X-Git-Tag: rel_0_6beta2~211 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e38b11928a4d0902dde5c45e0df99565df85d6ba;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Fixed bug in session.merge() blocking dict-like collections from merging. --- diff --git a/CHANGES b/CHANGES index 855293635a..96237de6cd 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,9 @@ CHANGES - Fixed bug in attribute history that inadvertently invoked __eq__ on mapped instances. + - Fixed bug in session.merge() which prevented dict-like + collections from merging. + - sql - Added math negation operator support, -x. diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 486aa2e4b7..8dbc6b3db7 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -645,7 +645,10 @@ class RelationProperty(StrategizedProperty): if self.uselist: instances = source_state.get_impl(self.key).\ get(source_state, source_dict) - + if hasattr(instances, '_sa_adapter'): + # convert collections to adapters to get a true iterator + instances = instances._sa_adapter + if load: # for a full merge, pre-load the destination collection, # so that individual _merge of each item pulls from identity diff --git a/test/aaa_profiling/test_orm.py b/test/aaa_profiling/test_orm.py index a95086509c..7bdc485ba9 100644 --- a/test/aaa_profiling/test_orm.py +++ b/test/aaa_profiling/test_orm.py @@ -58,7 +58,7 @@ class MergeTest(_base.MappedTest): # down from 185 on this # this is a small slice of a usually bigger # operation so using a small variance - @profiling.function_call_count(87, variance=0.001) + @profiling.function_call_count(91, variance=0.001) def go(): return sess2.merge(p1, load=False) diff --git a/test/orm/test_merge.py b/test/orm/test_merge.py index fab074d5c5..ca7c7942da 100644 --- a/test/orm/test_merge.py +++ b/test/orm/test_merge.py @@ -6,6 +6,7 @@ from sqlalchemy.test import testing from sqlalchemy.util import OrderedSet from sqlalchemy.orm import mapper, relation, create_session, PropComparator, \ synonym, comparable_property, sessionmaker, attributes +from sqlalchemy.orm.collections import attribute_mapped_collection from sqlalchemy.orm.interfaces import MapperOption from sqlalchemy.test.testing import eq_, ne_ from test.orm import _base, _fixtures @@ -245,7 +246,22 @@ class MergeTest(_fixtures.FixtureTest): sess.merge(u1) sess.flush() assert u1.address_id is u1.data is None - + + @testing.resolve_artifact_names + def test_merge_irregular_collection(self): + mapper(User, users, properties={ + 'addresses': relation( + mapper(Address, addresses), + backref='user', + collection_class=attribute_mapped_collection('email_address')), + }) + u1 = User(id=7, name='fred') + u1.addresses['foo@bar.com'] = Address(email_address='foo@bar.com') + sess = create_session() + sess.merge(u1) + sess.flush() + assert u1.addresses.keys() == ['foo@bar.com'] + @testing.resolve_artifact_names def test_attribute_cascade(self): """Merge of a persistent entity with two child persistent entities."""