2013-10-26 25 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

相关问题