2011-09-14 11 views
33

मेरे पास 3 टेबल हैं: उपयोगकर्ता, समुदाय, समुदाय_मेम्बर (रिश्ते के लिए कई उपयोगकर्ता और समुदाय)।अतिरिक्त क्षेत्रों के साथ SQLAlchemy ManyToMany माध्यमिक तालिका

community_members = db.Table('community_members', 
       db.Column('user_id', db.Integer, db.ForeignKey('user.id')), 
       db.Column('community_id', db.Integer, db.ForeignKey('community.id')), 
       ) 


class Community(db.Model): 
    __tablename__ = 'community' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(100), nullable=False, unique=True) 
    members = db.relationship(User, secondary=community_members, 
          backref=db.backref('community_members', lazy='dynamic')) 

अब मैं इस तरह community_members करने के लिए अतिरिक्त क्षेत्र जोड़ना चाहते हैं:

community_members = db.Table('community_members', 
       db.Column('id', db.Integer, primary_key=True), 
       db.Column('user_id', db.Integer, db.ForeignKey('user.id')), 
       db.Column('community_id', db.Integer, db.ForeignKey('community.id')), 
       db.Column('time_create', db.DateTime, nullable=False, default=func.now()), 
       ) 

और अब अजगर खोल में मैं यह कर सकता:

मैं इस टेबल कुप्पी के SQLAlchemy का उपयोग कर बनाने के

समुदाय बनाएं:

> c = Community() 
> c.name = 'c1' 
> db.session.add(c) 
> db.session.commit() 

समुदाय में सदस्यों को जोड़ने:

> u1 = User.query.get(1) 
> u2 = User.query.get(2) 
> c.members.append(u1) 
> c.members.append(u2) 
> db.session.commit() 

> c.members 
[<User 1>, <User 2>] 

ठीक है, यह काम करता है।

लेकिन अब मैं community_members तालिका का समय_क्रेट कैसे प्राप्त कर सकता हूं?

उत्तर

46

आपको "एसोसिएशन ऑब्जेक्ट" का उपयोग करने के लिए एक सादे, कई से अधिक रिश्तों का उपयोग करने से स्विच करना होगा, जो मूल रूप से केवल एसोसिएशन टेबल ले रहा है और इसे उचित वर्ग मैपिंग दे रहा है। तुम तो एक-से-कई रिश्तों User और Community को परिभाषित करेंगे:

class Membership(db.Model): 
    __tablename__ = 'community_members' 

    id = db.Column('id', db.Integer, primary_key=True) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id')) 
    community_id = db.Column(db.Integer, db.ForeignKey('community.id')) 
    time_create = db.Column(db.DateTime, nullable=False, default=func.now()) 

    community = db.relationship(Community, backref="memberships") 
    user = db.relationship(User, backref="memberships") 


class Community(db.Model): 
    __tablename__ = 'community' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(100), nullable=False, unique=True) 

लेकिन आप कभी कभी ही पैदा करते समय में रुचि हो सकती; आप पुराने रिश्ते को वापस चाहते हैं! ठीक है, आप relationship दो बार सेट अप नहीं करना चाहते हैं; क्योंकि sqlalchemy सोचता है कि आप किसी भी तरह दो एसोसिएशन चाहते हैं; जिसका मतलब कुछ अलग होना चाहिए! आप एक association proxy.

from sqlalchemy.ext.associationproxy import association_proxy 

Community.members = association_proxy("memberships", "user") 
User.communities = association_proxy("memberships", "community") 
+6

मैंने आपके समाधान का उपयोग किया और यह काम किया, लेकिन मुझे अभी भी एक समस्या है। क्या यह संभव है कि Community.members (एसोसिएशन प्रॉक्सी के साथ जोड़ा गया) एक AppenderBaseQuery लौटाएं कि मैं अधिक फ़िल्टर जोड़ सकता हूं, उदा। Community.members.filter_by (...)? मैं रिश्ते की घोषणा में आलसी = गतिशील का उपयोग करके सादा कई से कई रिश्ते के साथ ऐसा करने के लिए प्रयोग किया जाता था, लेकिन एसोसिएशन टेबल में कक्षा मैपिंग देने के बाद ऐसा लगता है कि मैं इसे और नहीं कर सकता। – stefanobaldo

+0

क्या आपने कभी समाधान @stefanobaldo खोजा है - यदि आपने किया तो वास्तव में सहायक होगा! – pip

0

में जोड़ कर ऐसा कर सकते हैं तो आप केवल क्वेरी community_members और एक ज्ञात user_id द्वारा community मेज की जरूरत है (जैसे user_id = 2), SQLAlchemy में, आप कर सकते हैं:

session.query(community_members.c.time_create, Community.name).filter(community_members.c.user_id==2)

परिणाम प्राप्त करने के लिए

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