2009-12-11 16 views
10

मेरे पास मेरे एप्लिकेशन में एक स्क्लेक्लेमी मॉडल स्थापित है जो ट्विटर पर "अनुयायियों" की कार्यक्षमता की नकल करना चाहिए, यानी। उपयोगकर्ताओं के पास एक दूसरे के साथ कई से अधिक संबंध हैं (दोनों अनुयायियों और निम्नलिखित)।SQLAlchemy एकल तालिका पर कई से अधिक रिश्ते

t_users = sa.Table("users", meta.metadata, 
    sa.Column("id", sa.types.Integer, primary_key=True), 
    sa.Column("email", sa.types.String(320), unique=True, nullable=False), 
    ...etc... 
    ) 

t_follows = sa.Table("follows", meta.metadata, 
    sa.Column("id", sa.types.Integer, primary_key=True), 
    sa.Column("follower_id", sa.types.Integer, sa.ForeignKey('users.id'), nullable=False), 
    sa.Column("followee_id", sa.types.Integer, sa.ForeignKey('users.id'), nullable=False) 
    ) 

मैं एक अवरोध तथापि का एक सा आई है इस संबंध बनाने के लिए orm.mapper उपयोग करने के लिए कोशिश कर रहा है, माध्यमिक तालिका वापस संदर्भित करता है के बाद से: टेबल इस प्रकार संरचित कर रहे (सा SQLAlchemy मॉड्यूल है) दोनों दिशाओं में एक ही प्राथमिक तालिका में। ओआरएम से इस संबंध को मैप करने के बारे में मैं कैसे जाउंगा?

उत्तर

6

आप इस मामले में स्पष्ट रूप से primaryjoin और secondaryjoin स्थिति लिखने के लिए है:

mapper(
    User, t_users, 
    properties={ 
     'followers': relation(
      User, 
      secondary=t_follows, 
      primaryjoin=(t_follows.c.followee_id==t_users.c.id), 
      secondaryjoin=(t_follows.c.follower_id==t_users.c.id), 
     ), 
     'followees': relation(
      User, 
      secondary=t_follows, 
      primaryjoin=(t_follows.c.follower_id==t_users.c.id), 
      secondaryjoin=(t_follows.c.followee_id==t_users.c.id), 
     ), 
    }, 
) 

मैं वर्बोज़ इस नमूने लिखा गया है तो आप बेहतर primaryjoin और secondaryjoin मापदंडों क्या मतलब समझ सकें। निश्चित रूप से, आप इसे backref के साथ सॉर्टर बना सकते हैं।

बीटीडब्ल्यू, आपको निम्न तालिका में id कॉलम की आवश्यकता नहीं है, इसके बजाय समग्र प्राथमिक कुंजी का उपयोग करें। वास्तव में, आपको follower_id और followee_id किसी भी तरह की जोड़ी (या तो प्राथमिक या अतिरिक्त अद्वितीय कुंजी) के अद्वितीय बाधा को परिभाषित करना चाहिए।

+0

धन्यवाद, यह पूरी तरह से काम करता है। क्या आपका मतलब है कि निम्न तालिका को आईडी कॉलम की आवश्यकता नहीं है और एक समग्र पीके का उपयोग कर सकते हैं? मैं नहीं देखता कि यह उपयोगकर्ता तालिका के साथ कैसे काम कर सकता है। – Travis

+0

हां, यह एक गलती थी। मेरा मतलब टेबल का पालन करना था। –

+0

मैं इसमें भाग गया और इसे घोषणात्मक रूप से करना था, यहां भविष्य के खोजकर्ताओं के बराबर है। –

14

आप यह घोषणा भी कर सकते हैं।

यहां उपरोक्त कोड के आधार पर एक समान उदाहरण है, मैं बैकफ्रू का उपयोग करता हूं।

VolumeRelationship = Table(
    'VolumeRelationship', Base.metadata, 
    Column('ParentID', Integer, ForeignKey('Volumes.ID')), 
    Column('VolumeID', Integer, ForeignKey('Volumes.ID')) 
    ) 

class Volume(Base): 
    """ Volume Object """ 
    __tablename__ = "Volumes" 

    id = Column('ID', Integer, primary_key=True, nullable=False) 
    type = Column('Type', String(25)) 
    name = Column('Name', String(25)) 
    poolid = Column('pool', Integer, ForeignKey('Pools.ID')) 
    parents = relation(
        'Volume',secondary=VolumeRelationship, 
        primaryjoin=VolumeRelationship.c.VolumeID==id, 
        secondaryjoin=VolumeRelationship.c.ParentID==id, 
        backref="children") 
+0

लिए मुझे, मैं had को add analogue की 'foreign_keys = [VolumeRelationship.c.VolumeID, VolumeRelationship.c.ParentID])' को 'Volume.parents', otherwise मैं had' NoReferencedTableError'। –

संबंधित मुद्दे