Michael Bayer wrote: > > i think using the polymorphic_map is OK. i downplayed its > existence since I felt it was confusing to people, which is > also the reason i made the _polymorphic_map argument to > mapper "private"; it was originally public. but it seemed > like it was producing two ways of doing the same thing so i > made it private.
OK - I'll carry on using that then. > > <using class_mapper() function instead of class.mapper> > Ah - that's what I was missing. I hadn't seen the class_mapper function. Thanks for that. > > as far as having multiple "polymorphic_identity" values map > to the same class, i would think we could just have > polymorphic_identity be a list instead of a scalar. right > now, if you just inserted multiple values for the same class > in polymorphic_map, it would *almost* work except that the > save() process is hardwiring the polymorphic_on column to the > single polymorphic_identity value no matter what its set to. > > so attached is an untested patch which accepts either a > scalar or a list value for polymorphic_identity, and if its a > list then instances need their "polymorphic_on" attribute set > to a valid entry before flushing. try this out and see if it > does what you need, and i can easily enough add this to the > trunk to be available in the next release (though id need to > write some tests also). > I think this would definitely be a useful feature, and in fact I was originally going to attempt (or at least suggest!) something like that myself. I'll try the patch and let you know how well it works. However, I still have a situation where I would like to be able to use a default class for unknown types. I don't want to hard-code all the possible options up-front - only the ones that I actually want to treat specially. I've been playing around with some different options, and this is what I've ended up with: class EmployeeMeta(type): def __call__(cls, kind, _fix_class=True, **kwargs): if not _fix_class: return type.__call__(cls, kind=kind, **kwargs) cls = get_employee_class(kind) return cls(kind=kind, _fix_class=False, **kwargs) def get_employee_class(kind): if kind == 'manager': return Manager else: return Employee class Employee(object): __metaclass__ = EmployeeMeta class Manager(Employee): pass class EmployeeMapperExtension(sa.MapperExtension): def create_instance(self, mapper, selectcontext, row, class_): cls = get_employee_class(row[employee_table.c.kind]) if class_ != cls: return sa.class_mapper(cls)._instance(selectcontext, row) return sa.EXT_PASS assign_mapper(ctx, Employee, employee_table, extension=EmployeeMapperExtension()) assign_mapper(ctx, Manager, inherits=Employee.mapper) This seems to do the right thing - Manager instances get created for managers, but any other row becomes an Employee. To add a subclass for another row type, I just need to adapt the get_employee_class function and add another call to assign_mapper. With a bit more work in the metaclass, it could all be done with a special attribute in the subclass. The only thing I'm not sure about is the mapper extension - is it OK to call the mapper._instance method, or is there a better way to do this? Thanks again, 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 -~----------~----~----~----~------~----~------~--~---
inheritance_test.py
Description: inheritance_test.py