the history of with_polymorphic spans back to the time when we didn't have 
declarative and just the mapper() call was used, at which point any particular 
subclass would also be available, and yes you certainly can pass a specific 
list of classes to the mapper-level with_polymorphic - the with_polymorphic 
argument on mapper() takes the exact same argument format as the 
with_polymorphic() method on Query.

It's the declarative system that is not letting you do it, as this is not a 
common use case, but the reason is because the hook you're using is called 
during the creation of the Test class, necessarily before any subclass of Test 
exists.

One thing hit me about your use case - that a particular Python environment 
will only use one of these subclasses at a time.    The ORM has less guesswork 
to do if you in fact use the PolyTest class directly in queries, instead of 
querying against the base Test.    If it were me, I'd not bother with 
"polymorphic" at all, and just set up a reference to the class that the app 
needs:

class Test(...):
    ....

class PolyTest(...):
   ...

# fastcgi environment thing:

MyClass = PolyTest # (or PolyTest2, or PolyTest18, whatever your fastcgi thing 
sets up)

Using the subclass directly has the advantage that you can directly refer to 
those attributes that are specific to PolyTest in queries without switching 
classes.  Suppose Test has a column "x" and PolyTest has a column "y".   The 
with_polymorphic approach might have you doing this kind of thing:

        query(Test).filter(PolyTest.y == 'value').filter(Test.x == 'value')

whereas if you just use PolyTest, or some alias, simpler:

        query(MyClass).filter(MyClass.y == 'value').filter(MyClass.x == 'value')


Anyway, if you don't want to do that, then just set with_polymorphic after the 
fact, which you can do using _set_with_polymorphic():

        Test.__mapper__._set_with_polymorphic([PolyTest])

_set_with_polymorphic() was added in the middle of the 0.7 series to support 
the ConcreteBase system, which has this same need, that is, to set up 
with_polymorphic on the base class of a mapper hierarchy.   You can also do it 
via your declarative using __declare_last__():

class Test(...):
    @classmethod
    def __declare_last__(cls):
        m = cls.__mapper__

        # don't set it twice, if multiple mapper configs occur
        if m.with_polymorphic:
            return

        m._set_with_polymorphic([PolyTest])

__declare_last__() is basically a class-level hook that's triggered by the 
"after_configured" mapper event, which you could also use directly.






On Dec 7, 2012, at 7:56 PM, Gerald Thibault wrote:

> I have a test file (attached below) with a base class called Test, and an 
> extended class called PolyTest, which is a polymorphic subclass of Test.
> 
> I want to query for Test and get back a full PolyTest object. I do not want 
> to use with_polymorphic: '*', as we have a large number of subclasses, only 
> one of which will ever be used at a time (when the fastcgi environ is set, 
> the subclass is assigned, and will not change for the life of the server). 
> Each subclass is a globally used thing, so for client A, every instance of 
> Test will always be TestA, which has that client's unique params. Using * on 
> with_poly generated a monstrous query spanning every subtable we have, and is 
> not an option.
> 
> So, given that PolyTest inherits from Test (implying test needs to be mapped 
> first), how do I pass the subclass PolyTest into the mapper_args of Test? 
> There is not a single example on the entire site which provides guidance, as 
> every single occurrence of with_polymorphic occurring within mapper args is 
> using '*'. This makes me wonder if it is even possible, because I can't find 
> a single example anywhere of someone passing classes into 
> mapper_args['with_poly'].
> 
> In the enclosed test, the final print should have a value attribute in it, 
> which it does not.
> 
> Also, using query.with_polymorphic is not a reasonable option here, as we 
> have a huge platform which expects to query() and get back the exact result. 
> We're not planning on replacing every instance of 'query()' in our codebase.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To view this discussion on the web visit 
> https://groups.google.com/d/msg/sqlalchemy/-/l_78KhKtxogJ.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/sqlalchemy?hl=en.
> <with_poly_test.py>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to