2016-09-15 71 views
0

Managerクラスのowner_id = Column(Integer, ForeignKey('employees.employee_id'))という行のため、以下のコードは機能しません。 SQLAlchemyはエラーメッセージを生成します:SQLAlchemyは、2つの外部キーを持つ2つのテーブルを結合することはできません

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.

修正するのを助けてください!

アイデアは、すべてのマネージャが従業員であり、何人かのオーナーのために働くことです。所有者のために働いているマネージャーが0人、1人以上存在する可能性があります。

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

答えて

1

SQLAlchemyの約混乱している....と示さ関連分野の残りの部分を追加しますManagerEmployeeに結合する方法は、2つの表の間に複数の外部キーがあるため、employee_idowner_idです。この場合は、明示的マッパーにinherit_conditionを指定する必要があります。

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

親モデルの拡張と同じ親モデルへの関係の定義の両方が拡張されています。

単に一つの方法を使用して、あなたは、単に関係を作成でき、すべてのモデルが

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

基本クラスを拡張してきたが

+0

あなたは絶対的に継承し、同じモデルとの関係の両方を持つことができます。 – univerio

関連する問題