From: Mike Bayer Date: Wed, 13 Jan 2010 18:31:19 +0000 (+0000) Subject: - replace the tip of the path info with the subclass mapper being used. X-Git-Tag: rel_0_6beta1~76 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=db4af57e206b059a8d3e78a971834982fa8aa062;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - replace the tip of the path info with the subclass mapper being used. that way accurate "load_path" info is available for options invoked during deferred loads. we lose AliasedClass path elements this way, but currently, those are not needed at this stage. --- diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 9e03771051..5faa719d3f 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -1805,7 +1805,18 @@ class Mapper(object): raise AssertionError("No such polymorphic_identity %r is defined" % discriminator) if mapper is self: return None - return mapper._instance_processor(context, path, adapter, polymorphic_from=self) + + # replace the tip of the path info with the subclass mapper being used. + # that way accurate "load_path" info is available for options + # invoked during deferred loads. + # we lose AliasedClass path elements this way, but currently, + # those are not needed at this stage. + + # this asserts to true + #assert mapper.isa(_class_to_mapper(path[-1])) + + return mapper._instance_processor(context, path[0:-1] + (mapper,), + adapter, polymorphic_from=self) return configure_subclass_mapper log.class_logger(Mapper) diff --git a/test/orm/inheritance/test_query.py b/test/orm/inheritance/test_query.py index 0f9163ec06..1a7d09e92e 100644 --- a/test/orm/inheritance/test_query.py +++ b/test/orm/inheritance/test_query.py @@ -1,6 +1,7 @@ from sqlalchemy.test.testing import eq_, assert_raises, assert_raises_message from sqlalchemy import * from sqlalchemy.orm import * +from sqlalchemy.orm import interfaces from sqlalchemy import exc as sa_exc from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.engine import default @@ -379,6 +380,31 @@ def _produce_test(select_type): sess.query(malias.name).join((paperwork, malias.person_id==paperwork.c.person_id)).all(), [(u'pointy haired boss',), (u'dogbert',), (u'dogbert',)] ) + + def test_polymorphic_option(self): + """test that polymorphic loading sets state.load_path with its actual mapper + on a subclass, and not the superclass mapper. + + """ + paths = [] + class MyOption(interfaces.MapperOption): + propagate_to_loaders = True + def process_query_conditionally(self, query): + paths.append(query._current_path) + + sess = create_session() + dilbert, boss = sess.query(Person).\ + options(MyOption()).\ + filter(Person.name.in_(['dilbert', 'pointy haired boss'])).\ + order_by(Person.name).\ + all() + + dilbert.machines + boss.paperwork + eq_(paths, + [(class_mapper(Engineer), 'machines'), + (class_mapper(Boss), 'paperwork')]) + def test_expire(self): """test that individual column refresh doesn't get tripped up by the select_table mapper"""