m = m.inherits
def polymorphic_iterator(self):
- m = self.base_mapper()
+ """iterates through the collection including this mapper and all descendant mappers.
+
+ this includes not just the immediately inheriting mappers but all their inheriting mappers as well.
+
+ To iterate through an entire hierarchy, use mapper.base_mapper().polymorphic_iterator()."""
def iterate(m):
yield m
for mapper in m._inheriting_mappers:
for x in iterate(mapper):
yield x
- return iterate(m)
+ return iterate(self)
def add_properties(self, dict_of_properties):
"""adds the given dictionary of properties to this mapper, using add_property."""
updated_objects = util.Set()
table_to_mapper = {}
- for mapper in self.polymorphic_iterator():
+ for mapper in self.base_mapper().polymorphic_iterator():
for t in mapper.tables:
table_to_mapper.setdefault(t, mapper)
--- /dev/null
+from sqlalchemy import *
+import testbase
+
+class SingleInheritanceTest(testbase.AssertMixin):
+ def setUpAll(self):
+ metadata = BoundMetaData(testbase.db)
+ global employees_table
+ employees_table = Table('employees', metadata,
+ Column('employee_id', Integer, primary_key=True),
+ Column('name', String(50)),
+ Column('manager_data', String(50)),
+ Column('engineer_info', String(50)),
+ Column('type', String(20))
+ )
+ employees_table.create()
+ def tearDownAll(self):
+ employees_table.drop()
+ def testbasic(self):
+ class Employee(object):
+ def __init__(self, name):
+ self.name = name
+ def __repr__(self):
+ return self.__class__.__name__ + " " + self.name
+
+ class Manager(Employee):
+ def __init__(self, name, manager_data):
+ self.name = name
+ self.manager_data = manager_data
+ def __repr__(self):
+ return self.__class__.__name__ + " " + self.name + " " + self.manager_data
+
+ class Engineer(Employee):
+ def __init__(self, name, engineer_info):
+ self.name = name
+ self.engineer_info = engineer_info
+ def __repr__(self):
+ return self.__class__.__name__ + " " + self.name + " " + self.engineer_info
+
+ class JuniorEngineer(Engineer):
+ pass
+
+ employee_mapper = mapper(Employee, employees_table, polymorphic_on=employees_table.c.type)
+ manager_mapper = mapper(Manager, inherits=employee_mapper, polymorphic_identity='manager')
+ engineer_mapper = mapper(Engineer, inherits=employee_mapper, polymorphic_identity='engineer')
+ junior_engineer = mapper(JuniorEngineer, inherits=engineer_mapper, polymorphic_identity='juniorengineer')
+
+ session = create_session()
+
+ m1 = Manager('Tom', 'knows how to manage things')
+ e1 = Engineer('Kurt', 'knows how to hack')
+ e2 = JuniorEngineer('Ed', 'oh that ed')
+ session.save(m1)
+ session.save(e1)
+ session.save(e2)
+ session.flush()
+
+ assert session.query(Employee).select() == [m1, e1, e2]
+ assert session.query(Engineer).select() == [e1, e2]
+ assert session.query(Manager).select() == [m1]
+ assert session.query(JuniorEngineer).select() == [e2]
+
+if __name__ == '__main__':
+ testbase.main()
\ No newline at end of file