2013-10-26 24 views
1

我正在學習SQLAlchemy,我在做看似簡單的操作時遇到了麻煩。請原諒我,如果我的問題是原始的和基本的,但我不能爲我的生活弄清楚如何基本加入我的兩張桌子。如何在兩個表上進行基本連接?

我的表是這樣的:

class User(Base): 

    """ Basic User definition """ 

    __tablename__ = 'users' 

    id = Column(Integer, primary_key=True) 
    name = Column(Unicode(255)) 
    email = Column(Unicode(255), unique=True) 
    username = Column(Unicode(255), unique=True) 
    _password = Column('password', Unicode(60)) 

    contacts = relationship('Contact', backref='users') 
    contact_groups = relationship('ContactGroups', backref='users') 
    contact_group_users = relationship('ContactGroupUsers', backref='users') 

class Contact(Base): 

    __tablename__ = 'contacts' 

    id = Column(Integer, primary_key=True) 
    user_id = Column(Integer) 
    contact_id = Column(Integer) 

    __table_args__ = (ForeignKeyConstraint([contact_id], [User.id]), {}) 

class ContactGroups(Base): 

    __tablename__ = 'contact_groups' 

    id = Column(Integer, primary_key=True) 
    user_id = Column(Integer, ForeignKey('users.id')) 
    group_name = Column(Unicode(255)) 

    contact_group_users = relationship('ContactGroupUsers', backref='contact_groups') 

class ContactGroupUsers(Base): 

    __tablename__ = 'contact_group_users' 

    id = Column(Integer, primary_key=True) 
    group_id = Column(Integer, ForeignKey('contact_groups.id')) 
    user_id = Column(Integer, ForeignKey('users.id')) 

我有我的主要User表。用戶可以將其他用戶添加爲Contact。爲了幫助組織這些聯繫人,他們可以創建ContactGroups

Contact.user_idContact.contact_id應該是User.id的外鍵。

ContactGroupUsers.group_id是一個外鍵ContactGroup.id 而每ContactGroupUser.user_id是一個外鍵返回到該用戶的User.id。 (也許這是一個可怕的方式做......它可能是,但我學習。反正)

當我查詢存在於特定羣體的接觸,我想檢索所有行,其中filter(ContactGroupUsers.group_id == group_id).all()然後由此將每個ContactGroupUsers.user_id加入到該用戶在Contact表中的條目中。因此,我將最終得到的結果是:

ContactGroupUsers.group_id | (and then the information present in the contacts table for that user) 

所以,我的最後一個問題,我怎麼能根據User.id加入我的兩個表ContactGroupUsersContacts?或者,如果有一種固有的優越方式來做到這一點,請指出正確的方向,這樣我至少可以適當地學習。

感謝您的幫助。非常感激。

+0

你嘗試過什麼到目前爲止,看完之後http://docs.sqlalchemy.org/en/rel_0_8 /orm/tutorial.html#querying-with-joins? – cdaddr

回答

1

既然你是在Contact定義多個外鍵回到User,它可能是更好地界定它們如下:

from sqlalchemy.ext.associationproxy import association_proxy 

class User(Base): 

    __tablename__  = 'user' 

    id     = Column(Integer, primary_key=True) 

    contacts   = relationship('Contact', 
     primaryjoin = 'foreign(User.id)=remote(Contact.user_id)', 
     backref  = 'user' 
    ) 
    contact_groups  = relationship('ContactGroup', backref='user') 
    contact_group_users = relationship('ContactGroupUsers', backref='user') 

    contact_users = association_proxy('contacts', 'contact') 

class Contact(Base): 

    __tablename__  = 'contact' 

    id     = Column(Integer, primary_key=True) 

    user_id    = Column(Integer, ForeignKey('user.id')) 
    contact_id   = Column(Integer, ForeignKey('user.id')) 

    contact    = relationship('User', 
     primaryjoin = 'foreign(Contact.contact_id) = remote(User.id)', 
     backref  = 'user_contacts' 
    ) 

class ContactGroup(Base): 

    __tablename__  = 'contact_group' 

    id     = Column(Integer, primary_key=True) 

    user_id    = Column(Integer, ForeignKey('user.id')) 

class ContactGroupUser(Base): 

    __tablename__  = 'contact_group_user' 

    id     = Column(Integer, primary_key=True) 

    group_id   = Column(Integer, ForeignKey('contact_group.id')) 
    user_id    = Column(Integer, ForeignKey('user.id')) 

    contact_group  = relationship('ContactGroup') 

建立以這種格式的關係可能有點複雜,涉及的aliased用戶實例。你可以,例如,進行查詢如下說明在某些GROUP_ID所有給定用戶的聯繫人:

original_user = aliased(User) 

contacts = db.session.query(User)\ 
    .join(User.user_contacts)\ 
    .join(original_user, original_user.id == Contact.user_id)\ 
    .join(User.contact_group_users)\ 
    .join(ContactGroupUser.contact_groups).filter(
     and_(
      original_user.id == user_id, 
      contact_group.user_id == original_user.id, 
      contact_group.group_id == group_id 
     ) 
    ).all() 
+0

如果你想進入聯繫人'用戶'的信息存儲在'聯繫'記錄關聯兩者,你會希望你的查詢讀取像'contacts = db.session.query(用戶,聯繫人)' 。然後,您可以執行聯繫[0] .Contact或[conacts [0] .User'從任一表中獲取信息。 – astex

相關問題