I have run into an interesting condition when using joined table inheritance. For example we have the typical employee, manager and engineer tables with the following relationships:
- an engineer is an employee - a manager is an employee - an employee has a manager We find some interesting results when using this query: session.query(Employee.id, Engineer.id).join(Engineer.manager) The resulting SQL is: SELECT employee.id AS employee_id, engineer.id AS engineer_id FROM engineer, employee JOIN (employee AS employee_1 JOIN manager AS manager_1 ON manager_1.id = employee_1.id) ON manager_1.id = employee.manager_id Notice how the outer engineer and employee tables aren't joined. I would have expected the engineer and employee from the query() call to be joined. Example code: #!/usr/bin/env python from sqlalchemy import Column, Integer, String, Enum, __version__ from sqlalchemy import ForeignKey from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship print "sqlalchemy version", __version__ engine = create_engine('sqlite:///:memory:', echo=False) Base = declarative_base() class Employee(Base): __tablename__ = 'employee' id = Column(Integer, primary_key=True) name = Column(String, index=True, nullable=False) manager_id = Column( ForeignKey( 'manager.id', use_alter=True, name="manager_id_fkey" ), index=True, nullable=True) manager = relationship('Manager', foreign_keys=[manager_id]) employee_type = Column(Enum('manager', 'engineer', name='employee_type' )) __mapper_args__ = { 'polymorphic_identity': __tablename__, 'polymorphic_on': employee_type } class Manager(Employee): __tablename__ = 'manager' id = Column(Integer, ForeignKey('employee.id'), primary_key=True) __mapper_args__ = { 'polymorphic_identity': __tablename__, 'inherit_condition': id == Employee.id, } class Engineer(Employee): __tablename__ = 'engineer' id = Column(Integer, ForeignKey('employee.id'), primary_key=True) __mapper_args__ = { 'polymorphic_identity': __tablename__, 'inherit_condition': id == Employee.id, } Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) Session.configure(bind=engine) session = Session() the_boss = Manager(name='the boss') a_manager = Manager(name='a manager', manager=the_boss) engineer1 = Engineer(name='engineer 1', manager=a_manager) engineer2 = Engineer(name='engineer 2', manager=a_manager) session.add(engineer1) session.add(engineer2) session.commit() def test(test_number, query): print "\nTest", test_number print query print query.count() test(1, session.query(Engineer.id, Employee.id)) test(2, session.query(Employee.id, Engineer.id)) test(3, session.query(Engineer.id).outerjoin(Engineer.manager)) test(4, session.query(Employee.id).outerjoin(Engineer.manager)) test(5, session.query(Engineer.id, Employee.id).outerjoin(Engineer.manager)) test(6, session.query(Employee.id, Engineer.id).outerjoin(Engineer.manager)) The output sqlalchemy version 1.0.8 Test 1 SELECT engineer.id AS engineer_id, employee.id AS employee_id FROM employee JOIN engineer ON engineer.id = employee.id 2 Test 2 SELECT employee.id AS employee_id, engineer.id AS engineer_id FROM employee JOIN engineer ON engineer.id = employee.id 2 Test 3 SELECT engineer.id AS engineer_id FROM employee JOIN engineer ON engineer.id = employee.id LEFT OUTER JOIN (employee AS employee_1 JOIN manager AS manager_1 ON manager_1.id = employee_1.id) ON manager_1.id = employee.manager_id 2 Test 4 SELECT employee.id AS employee_id FROM employee LEFT OUTER JOIN (employee AS employee_1 JOIN manager AS manager_1 ON manager_1.id = employee_1.id) ON manager_1.id = employee. manager_id 4 Test 5 SELECT engineer.id AS engineer_id, employee.id AS employee_id FROM employee JOIN engineer ON engineer.id = employee.id LEFT OUTER JOIN (employee AS employee_1 JOIN manager AS manager_1 ON manager_1.id = employee_1.id) ON manager_1.id = employee.manager_id 2 Test 6 SELECT employee.id AS employee_id, engineer.id AS engineer_id FROM engineer, employee LEFT OUTER JOIN (employee AS employee_1 JOIN manager AS manager_1 ON manager_1.id = employee_1.id) ON manager_1.id = employee.manager_id 8- This is not an issue, as swapping the columns ends up with the expected results. However I'd like to understand what's going on. Thanks for your help -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.