2016-09-15 3 views
0

Der folgende Code funktioniert nicht aufgrund dieser Zeile owner_id = Column(Integer, ForeignKey('employees.employee_id')) in Manager-Klasse. SQLAlchemy generiert Fehlermeldung:SQLAlchemy kann nicht zwei Tabellen mit zwei Fremdschlüsseln zwischen ihnen verbinden

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.

Bitte helfen Sie, das zu beheben!

Die Idee ist, dass jeder Manager ein Mitarbeiter ist und für einige Besitzer arbeitet. Es kann null, einen oder mehrere Manager geben, die für einen Besitzer arbeiten.

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() 

Antwort

1

SQLAlchemy ist verwirrt wie man Manager zu Employee beitritt, weil Sie mehrere Fremdschlüssel zwischen den zwei Tabellen haben, employee_id und owner_id. In diesem Fall müssen Sie die inherit_condition zum Mapper explizit angeben:

class Manager(Employee): 
    __tablename__ = 'managers' 

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

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

    __mapper_args__ = {'polymorphic_identity': 'manager', 'inherit_condition': employee_id == Employee.employee_id} 
0

Sie erweitern sowohl das Elternmodell als auch die Beziehung zum selben Elternmodell.

einfach eine Möglichkeit nutzen, können Sie einfach Beziehungen erstellt und haben alle Ihre Modelle erweitern Basisklasse

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')) 
    ... 
    ... 

den Rest relevanten Feld hinzufügen, wo wie angegeben ....

+0

Sie unbedingt sowohl Vererbung und Beziehungen zu dem gleichen Modell haben kann. – univerio

Verwandte Themen