SQLAlchemy can't join two tables with two foreign keys between them
<p>The code below does not work due to this line <code>owner_id = Column(Integer, ForeignKey('employees.employee_id'))</code> in Manager class.  SQLAlchemy generates error message:</p>

<blockquote>
  <p>AmbiguousForeignKeysError: Can't determine join between 'employees' and > 'managers'; tables have more than one foreign key constraint relationship > between them. Please specify the 'onclause' of this join explicitly.</p>
</blockquote>

<p>Please help to fix that!</p>

<p>The idea is that every Manager is an Employee and works for some Owner. There might be zero, one or more Managers working for an Owner. </p>

<pre><code>from sqlalchemy import (Table, Column, Integer, String, create_engine,
    MetaData, ForeignKey)
from sqlalchemy.orm import mapper, create_session
from sqlalchemy.ext.declarative import declarative_base

e = create_engine('sqlite:////tmp/foo.db', echo=True)
Base = declarative_base(bind=e)

class Employee(Base):
    __tablename__ = 'employees'

    employee_id = Column(Integer, primary_key=True)
    name = Column(String(50))
    type = Column(String(30), nullable=False)

    __mapper_args__ = {'polymorphic_on': type}

    def __init__(self, name):
        self.name = name

class Manager(Employee):
    __tablename__ = 'managers'
    __mapper_args__ = {'polymorphic_identity': 'manager'}

    employee_id = Column(Integer, ForeignKey('employees.employee_id'),
                         primary_key=True)
    manager_data = Column(String(50))

    owner_id = Column(Integer, ForeignKey('employees.employee_id'))


    def __init__(self, name, manager_data):
        super(Manager, self).__init__(name)
        self.manager_data = manager_data

class Owner(Manager):
    __tablename__ = 'owners'
    __mapper_args__ = {'polymorphic_identity': 'owner'}

    employee_id = Column(Integer, ForeignKey('managers.employee_id'),
                         primary_key=True)
    owner_secret = Column(String(50))

    def __init__(self, name, manager_data, owner_secret):
        super(Owner, self).__init__(name, manager_data)
        self.owner_secret = owner_secret

Base.metadata.drop_all()
Base.metadata.create_all()

s = create_session(bind=e, autoflush=True, autocommit=False)    
o = Owner('nosklo', 'mgr001', 'ownerpwd')
s.add(o)
s.commit()
</code></pre>

<p>You are both extending parent model as well as defining relationship to the same parent model.</p>

<p>simply use one way, you could simply created relations and have all your models extend base class</p>

<pre><code>class Employee(Base):
    __tablename__ = 'employees'

    employee_id = Column(Integer, primary_key=True)
    ...
class Owner(Base):
    __tablename__ = 'owners'
    __mapper_args__ = {'polymorphic_identity': 'owner'}
    owner_id = Column(Integer, primary_key=True)
    ...
    ...
class Manager(Base):
    __tablename__ = 'managers'
    __mapper_args__ = {'polymorphic_identity': 'manager'}

    manager_id = Column(Integer, primary_key=True)
    employee_id = Column(Integer, ForeignKey('employees.employee_id'), primary_key=True)
    owner_id = Column(Integer, ForeignKey('owners.owner_id'))
    ...
    ...
</code></pre>

<p>add the rest of relevant field where indicated as ....</p>

python sqlalchemy