Hi,

I have a couple of questions about polymorphic mapper inheritance. I'll
use the employee/manager/engineer example from the docs, if that's OK.
I'm also using SessionContext and assign_mapper, in case that makes a
difference.

I'd like to be able to call the base class (Employee), but have it
actually generate an instance of the correct subclass. To do this, I'm
using a metaclass which looks something like:

class EmployeeMeta(type):
    def __call__(cls, kind, _fix_class=True):
        if not _fix_class:
            return type.__call__(cls, kind=kind)
        # Use the Employee mapper's polymorphic_map to figure out
        # which class to use
        mappers = Employee.mapper.polymorphic_map
        try:
            mapper = mappers[kind]
        except KeyError:
            raise ValueError('No such employee type: %s '
                             '(valid types are "%s")' %
                             (kind, ', '.join(mappers.keys())))
        cls = mapper.class_
        return cls(kind=kind, _fix_class=False)

This seems to work quite well - if I call Employee(type='manager'), I
get an instance of the Manager class back. However, I don't know
whether my use of the polymorphic_map dictionary is safe - is it
considered a public attribute or a private one? Also, the first time I
use this I have to explicitly compile the mapper, which makes it feel
slightly wrong.

My second question is also related to the polymorphic_map attribute. I
have another situation where it would be useful to produce subclasses
for certain employee types, but fall back to the base class for other
types. For example, imagine there were other employee types in the
table ('secretary', 'tester' etc.), and most of them don't need an
Employee subclass. Currently, I would get a KeyError if I tried to load
any of those rows (because the type doesn't exist in the
polymorphic_map). It would be nice to be able to specify a fallback in
some way. I can see two ways of doing it:

1. Use a MapperExtension. This is probably the correct way to do it,
but it seems a bit 'heavyweight', and I can't see a (public) way to ask
the mapper to create and populate an instance of a different class, so
I would end up having to duplicate a lot of the code from the mapper (a
lot of which I don't really understand ;-)

2. Pass in a dict-like object (such as python 2.5's defaultdict) as the
_polymorphic_map argument to the mapper. This would be an ugly hack as
the _polymorphic_map argument is very definitely private. However, it
is very simple, and it would also work with the metaclass described
above.

This is probably the sort of thing which is very specific to my
situation, and SQLAlchemy shouldn't guess what I want to do, which is
why I think the MapperExtension is probably the right way to go. I just
wish it were easier to ask the mapper to use a different class.

Thanks,

Simon


--~--~---------~--~----~------------~-------~--~----~
 You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
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