From 0875860acd322dce0d947d800889e7aae1376c10 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 21 Dec 2007 21:55:20 +0000 Subject: [PATCH] some rudimentary fixes to get instance-level deferreds/lazy loads to transfer over on merge() --- lib/sqlalchemy/orm/properties.py | 11 +++++++++-- test/orm/pickled.py | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index aadac5122c..e0bf2e6e81 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -65,8 +65,13 @@ class ColumnProperty(StrategizedProperty): getattr(state.class_, self.key).impl.set(state, value, None) def merge(self, session, source, dest, dont_load, _recursive): - setattr(dest, self.key, getattr(source, self.key, None)) - + value = attributes.get_as_list(source._state, self.key, passive=True) + if value: + setattr(dest, self.key, value[0]) + else: + # TODO: lazy callable should merge to the new instance + dest._state.expire_attributes([self.key]) + def get_col_value(self, column, value): return value @@ -334,6 +339,8 @@ class PropertyLoader(StrategizedProperty): def merge(self, session, source, dest, dont_load, _recursive): if not "merge" in self.cascade: + # TODO: lazy callable should merge to the new instance + dest._state.expire_attributes([self.key]) return instances = attributes.get_as_list(source._state, self.key, passive=True) if not instances: diff --git a/test/orm/pickled.py b/test/orm/pickled.py index eac6280242..a9a973cc0d 100644 --- a/test/orm/pickled.py +++ b/test/orm/pickled.py @@ -54,6 +54,12 @@ class PickleTest(FixtureTest): sess2.update(u2) self.assertEquals(u2.name, 'ed') self.assertEquals(u2, User(name='ed', addresses=[Address(email_address='ed@bar.com')])) + + u2 = pickle.loads(pickle.dumps(u1)) + sess2 = create_session() + u2 = sess2.merge(u2, dont_load=True) + self.assertEquals(u2.name, 'ed') + self.assertEquals(u2, User(name='ed', addresses=[Address(email_address='ed@bar.com')])) def test_instance_deferred_cols(self): mapper(User, users, properties={ @@ -76,12 +82,23 @@ class PickleTest(FixtureTest): sess2 = create_session() sess2.update(u2) self.assertEquals(u2.name, 'ed') - assert 'addresses' not in u1.__dict__ + assert 'addresses' not in u2.__dict__ ad = u2.addresses[0] assert 'email_address' not in ad.__dict__ self.assertEquals(ad.email_address, 'ed@bar.com') self.assertEquals(u2, User(name='ed', addresses=[Address(email_address='ed@bar.com')])) + u2 = pickle.loads(pickle.dumps(u1)) + sess2 = create_session() + u2 = sess2.merge(u2, dont_load=True) + self.assertEquals(u2.name, 'ed') + assert 'addresses' not in u2.__dict__ + ad = u2.addresses[0] + assert 'email_address' in ad.__dict__ # mapper options dont transmit over merge() right now + self.assertEquals(ad.email_address, 'ed@bar.com') + self.assertEquals(u2, User(name='ed', addresses=[Address(email_address='ed@bar.com')])) + + class PolymorphicDeferredTest(ORMTest): def define_tables(self, metadata): global users, email_users -- 2.47.3