]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- replace the tip of the path info with the subclass mapper being used.
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 13 Jan 2010 18:31:19 +0000 (18:31 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 13 Jan 2010 18:31:19 +0000 (18:31 +0000)
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.

lib/sqlalchemy/orm/mapper.py
test/orm/inheritance/test_query.py

index 9e03771051ab87b1e93b2df9c089952c19b08a3b..5faa719d3f2df3e8e6704ee18733fad7559777de 100644 (file)
@@ -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)
index 0f9163ec0645dc2dfef9c2146d4d7102f8202046..1a7d09e92ecd1fb41b40eb44f710d467453de7da 100644 (file)
@@ -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"""