SqlAlchemy表和查询问题

时间:2015-01-27 14:05:43

标签: python sqlalchemy

仍然围着SqlAlchemy缠头,遇到了一些问题。不确定是不是因为我正在创建关系不正确,查询不正确,或两者兼而有之。

一般的想法是......

  1. 从位置到用户的一对多(一个位置可以有很多用户,但用户只能有一个位置)。
  2. 组和用户之间的多对多(用户可以是许多组的成员,组可以有许多成员)。
  3. 与desc和用户的#2相同。
  4. 我的表格创建如下:

    Base = declarative_base()
    
    class Location(Base):
        __tablename__ = 'location'
        id = Column(Integer, primary_key=True)
        name = Column(String)
    
    group_user_association_table = Table('group_user_association_table', Base.metadata,
                               Column('group_id', Integer, ForeignKey('group.id')),
                               Column('user_id', Integer, ForeignKey('user.id')))
    class Group(Base):
        __tablename__ = 'group'
        id = Column(Integer, primary_key=True)
        name = Column(String)
        users = relationship('User', secondary=group_user_association_table, backref='group')
    
    desc_user_association_table = Table('desc_user_association', Base.metadata,
                                Column('desc_id', Integer, ForeignKey('desc.id')),
                                Column('user_id', Integer, ForeignKey('user.id')))
    
    class Desc(Base):
        __tablename__ = 'desc'
        id = Column(Integer, primary_key=True)
        name = Column(String)
        users = relationship('User', secondary=desc_user_association_table, backref='desc')
    
    class User(Base):
        __tablename__ = 'user'
        id = Column(Integer, primary_key=True)
        user_name = Column(String)
        location_id = Column(Integer, ForeignKey('location.id'))
        groups = Column(String, ForeignKey('group.id'))
        descs = Column(String, ForeignKey('desc.id'))
        location = relationship('Location', backref='user')
    

    以下是一些关于如何创建数据的示例(所有数据都是从网上抓取的):

    location = Location(id=city[1], name=city[0]) #city = ('name', id)
    profile = User()
    profile.id = int(str(span2class[0].a['href'][7:]))
    profile.user_name = str(span2class[0].a.img['alt'])
    profile.location_id = location.id
    
    g = Group(id=gid, name=str(group.contents[0])) # add the group to the Group table
    self.db_session.add(g)
    # Now add the gid to a list that will be added to the profile that eventually gets added to the user table
    profile.groups.append(str(gid)) # stick the gid into the list
    profile.groups = ','.join(profile.groups) # convert list to csv string
    # Repeat basically same thing above for desc
    
    self.db_session.add(profile)
    self.db_session.commit()
    

    就查询而言,我已经完成了一些基本工作,例如:

    for instance in db_session.query(User).all():
        print instance.id, instance.user_name
    

    但是当执行连接以获取(例如)特定user.id的group.id和group.name时......我尝试过的任何事情都没有用。我猜这个表格会是这样的:

    db_session.query(User, Group).join('users').filter(User.id==42)
    

    但这没有用。

1 个答案:

答案 0 :(得分:0)

从左到右连接作品,因此您应加入从UserGroup的关系:

db_session.query(User, Group).join(User.group).filter(User.id == 42)

但是这会返回一个元组列表(<User>, <Group>),因此如果用户属于2个或更多组,您将收到2行或更多行。

如果您真的想在一个(SQL)查询中加载用户及其组,更好的方法是加载用户,但配置查询以预加载组:

u = (session.query(User)
     .options(joinedload(User.group))
     .get(42)
     )

print("User = {}".format(u))
for g in u.group:
    print("  Group = {}".format(g))