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
example_tb.err
Description: Binary data

