2011-02-01 184 views
3

我有一個大致的用戶對象爲我的網站建成一個基類使用連接表SQLAlchemy的,繼承和關係


class User(Base): 
    __tablename__ = "auth_user" 

    id = Column(Integer, primary_key = True) 
    username = Column(String(100), nullable = False, unique = True, index = True) 
    ... 
    type = Column(String(1)) 
    __mapper_args__ = {'polymorphic_on' : type, "extension" : HashExtension()} 

然後我有一個基於此類


class Staff(User): 
    __tablename__ = "auth_staff" 
    __mapper_args__ = {'polymorphic_identity' : 's'}  
    id = Column(Integer, ForeignKey('auth_user.id'), primary_key = True) 

現在員工對象我也有一個候選對象,再從用戶得到的


class Candidate(User): 
    __tablename__ = "candidates_candidate" 
    __mapper_args__ = {'polymorphic_identity' : 'c'} 
    id = Column(Integer, ForeignKey('auth_user.id'), primary_key = True) 
    ... 
    staff_id = Column(Integer, ForeignKey("auth_user.id"), nullable = False) 

    staff = relationship("Staff", backref = backref("candidates", order_by = id)) 

所有的罰款;對C和結束idate對象。我希望它鏈接回一個Staff對象,但是我得到的錯誤是沒有一個'primaryjoin',我對這個關係應該如何鏈接到Staff對象感到困惑 - 如果它作爲Staff派生鏈接到User對象從它?....

任何建議將受到歡迎

~~~~~~~~~更新2月3日~~~~~~~~~~~~~~

修改後的代碼 - 仍會拋出關於主連接的錯誤。如果我添加一個primaryjoin它仍然扼流圈


#!/usr/bin/env python 
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean 
from sqlalchemy.orm import relationship, backref, sessionmaker 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import create_engine 

class DomainBase(object): 
    active = Column(Boolean, default = True, nullable = False) 

    def __str__(self): 
     return repr(self) 

Base = declarative_base(cls = DomainBase) 

class User(Base): 
    __tablename__ = "auth_user" 

    id = Column(Integer, primary_key = True) 
    username = Column(String(100), nullable = False, unique = True, index = True) 
    type = Column(String(1)) 
    __mapper_args__ = {'polymorphic_on' : type} 
class Staff(User): 
    __tablename__ = "auth_staff" 
    __mapper_args__ = {'polymorphic_identity' : 's'}  
    id = Column(Integer, ForeignKey('auth_user.id'), primary_key = True) 


class Candidate(User): 
    __tablename__ = "candidates_candidate" 
    __mapper_args__ = {'polymorphic_identity' : 'c'} 
    id = Column(Integer, ForeignKey('auth_user.id'), primary_key = True) 
    staff_id = Column(Integer, ForeignKey("auth_staff.id"), nullable = False) 

    staff = relationship("Staff", backref = backref("candidates", order_by = id)) 


engine = create_engine('sqlite:///:memory:') 
Base.metadata.create_all(engine) 

Session = sessionmaker(bind = engine, autocommit=True) 
session = Session() 

with session.begin(): 
    s = Staff(username = "DaveSmith") 
    session.add_all([s]) 

回答

3

你的示例使用2個外鍵基類表,這樣的SQLAlchemy不能確定1)應該使用的外鍵繼承加盟,2)有什麼外鍵用於員工關係。你必須爲這兩種情況指定提示。前者需要'inherit_condition'選項__mapper_args__(請參閱此answer for more info),稍後需要primaryjoin=(staff_id==User.id)參數relationship

但是請注意,您的staff關係指的是Staff類,而staff_id的外鍵指的是User的表。雖然你有一些共鳴,但在大多數情況下並不好。 更改staff_id定義使用ForeignKey("auth_staff.id")將解決您的問題,無需其他更改。

+0

正如你所說的那樣改變staff_id是有意義的,但它仍然與「ArgumentError:無法確定關係Candidate.staff上的父/子表之間的連接條件。指定'primaryjoin'表達式。如果'secondary'存在,'secondaryjoin'也是需要的。「 Staff.id是User.id的外鍵嗎? – Dumah 2011-02-01 21:33:11