Thanks for the quick reply.

The example is helpful but, as you mentioned, it doesn't get us to the case where we can have two (or more) subclasses with large sets of different attributes.

Its true that the method you use in the polymorphic example is basically filtered mapping. I think it would perform better with a single table though even if it were more messy. I wasn't too clear in what I was trying to do with mapping against selects, and I suspect that I may be way off course in how the technique can be used, but I am attaching an example.py and an example_tb.err file with the traceback from the error that occurs when I run it. Basically I have one table called tests, and then two classes Test1 and Test2. An instance of a Test1 should only have a way to load and save from/to the column data1 while Test2 should only be able to load/save from the column data2. A good default behavior would be to leave those columns as None or Null. If this could work then it wouldn't be too hard to create complex inheritance structures in a single table, and it'd have the added benefit of being very easy to reference a set of different types in the same inheritance tree via some relation.

Let me know if this makes any sense, or if I should stop trying to pursue a solution along these lines.

Thanks,
Michael
import sys
from sqlalchemy import *
from traceback import print_tb

tests = Table('tests',
    Column('id', Integer, primary_key=True),
    Column('type', String),
    Column('data1', Integer),
    Column('data2', String))
    


class Test1(object):
    def __repr__(self): return "Test1: %s" % self.data1
    


class Test2(object):
    def __repr__(self): return "Test2: %s" % self.data2

    


class TestLoader( MapperExtension ):
    def create_instance(self, mapper, row, imap, class_):
        if row['type'] == 'test1': return Test1()
        if row['type'] == 'test2': return Test2()
        raise "SoNowWhat", row
    
    def before_insert(self, mapper, instance):
        pass
    


test1select = select([tests.c.id, tests.c.type, tests.c.data1]).alias('test1select')

test2select = select([tests.c.id, tests.c.type, tests.c.data2]).alias('test2select')

ext = TestLoader()

global_connect('sqlite://', echo=True, echo_uow=True)    

assign_mapper(Test1, test1select, extension=ext)
assign_mapper(Test2, test2select, extension=ext)

tests.create()

first = Test1(data=5)
second = Test2(data="hi")


try:
    objectstore.commit()
except:
    tag, error, traceback = sys.exc_info()
    file = open('example_tb.err', 'w')
    print_tb(traceback, limit=None, file=file)
    file.close()
    raise
    
    





Attachment: example_tb.err
Description: Binary data

Reply via email to