2011-02-12 12 views
7

में एकाधिक आत्म रेफरेंसियल रिश्ते मेरे पास एक डेटाबेस मॉडल है जहां मुझे एक से कई रिश्तों और दो-से-एक संबंधों की आवश्यकता है। यहाँ मॉडल मैं कर दिया है, लेकिन यह त्रुटियोंएसक्यूएलकेमी

class Page(Base): 
    __tablename__ = 'pages' 
    id   = Column(Integer, primary_key=True) 
    title  = Column(String(100), nullable=False) 
    content  = Column(Text, nullable=False) 

    parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True) 
    children = relationship("Page", backref=backref("parent", remote_side=id)) 

    next_id  = Column(Integer, ForeignKey("pages.id"), nullable=True) 
    next  = relationship("Page", backref=backref("prev", remote_side=id, uselist=False)) 

    prev_id  = Column(Integer, ForeignKey("pages.id"), nullable=True) 
    prev  = relationship("Page", backref=backref("next", remote_side=id, uselist=False)) 

    def __init__(self, title, content, parent_id=None, next_id=None, prev_id=None): 
     self.title = title 
     self.content = content 
     self.parent_id = parent_id 
     self.next_id = next_id 
     self.prev_id = prev_id 

    def __repr__(self): 
     return '<Page "%r">' % self.title 

मैं निम्नलिखित त्रुटि मिलती है जब भी मैं डेटाबेस के लिए कुछ भी करने की कोशिश

ArgumentError: Could not determine join condition between parent/child tables on relationship Page.children. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well. 

क्या वास्तव में अजीब है कि यह अगले बिना काम किया है फेंक रहा है और पिछला कॉलम। किसी को पता है कि क्या गलत है?

उत्तर

14

विषय पुराना है, लेकिन चूंकि यह इतना भ्रमित है कि मैं इसे लिखूंगा।
आपको अलग 'पिछला' कॉलम की आवश्यकता नहीं है, आपके पास पहले से ही 'अगली' के लिए बैकफ्रफ़ है। मैन्युअल रूप से जुड़ जाता है इसके अतिरिक्त, क्योंकि आप एक ही लक्ष्य के लिए कई विदेशी कुंजी है, तो आप प्राथमिक निर्दिष्ट करना होगा:

class Page(Base): 
    __tablename__ = 'pages' 
    id   = Column(Integer, primary_key=True) 
    title  = Column(String(100), nullable=False) 
    content  = Column(Text, nullable=False) 

    parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True) 
    parent  = relationship("Page", 
        primaryjoin=('pages.c.id==pages.c.parent_id'), 
        remote_side='Page.id', 
        backref=backref("children")) 

    next_id  = Column(Integer, ForeignKey("pages.id"), nullable=True) 
    next  = relationship("Page", 
        primaryjoin=('pages.c.next_id==pages.c.id'), 
        remote_side='Page.id', 
        backref=backref("prev", uselist=False)) 

कीड़े या अजीब व्यवहार मैं देखा की बस बिट्स के एक जोड़े:
- आप केवल कर सकते हैं remote_side="Page.id" का उपयोग करें, remote_side=[id] नहीं और remote_side=["Page.id"] नहीं, या यह काम नहीं करेगा (sqlalchemy 0.6.6)। यह पिन करने के लिए परेशान था।
- ऐसा लगता है कि आपको हमेशा प्राथमिक रिमोट साइड के बावजूद प्राथमिक कुंजी के साथ remote_side का उपयोग करना चाहिए। remote_side="Pages.next_id" हमेशा एक अजीब त्रुटि उत्पन्न करेगा, भले ही यह उचित लगे।
- प्राथमिकजॉइंट अभिव्यक्ति नरक के रूप में भ्रमित है, क्योंकि यह उपनाम का उपयोग नहीं करती है, लेकिन यह वास्तव में ऐसा करने का सही तरीका है। बाध्यकारी इंजन जानता है कि किस अभिव्यक्ति को पैरामीटर के साथ प्रतिस्थापित करना है (जो कि बहुत ही निहित है और जेन, बीटीडब्ल्यू के खिलाफ है)।

1

आप foreign_keys उपयोग कर सकते हैं:

class Page(Base): 
    __tablename__ = 'pages' 
    id   = Column(Integer, primary_key=True) 
    title  = Column(String(100), nullable=False) 
    content  = Column(Text, nullable=False) 

    parent_id = Column(Integer, ForeignKey("pages.id"), nullable=True) 
    parent  = relationship("Page", 
        foreign_keys=[parent_id], 
        remote_side=[id], 
        backref=backref("children")) 

    next_id  = Column(Integer, ForeignKey("pages.id"), nullable=True) 
    next  = relationship("Page", 
        foreign_keys=[next_id], 
        remote_side=[id], 
        backref=backref("prev", uselist=False)) 
संबंधित मुद्दे