SQLAlchemy连接多个表以检索数据

8
我正在使用SQLAlchemy的.join()方法从多个表中检索数据。运行查询时,我期望得到一个包含来自不同表连接的所有数据的单个对象,以便我可以在其中使用a.area_name等内容,其中area_name位于其中一个连接表上。以下是我正在运行的查询和表格布局,如果有人能够提供关于如何实现我所需行为的见解,我将非常感激!我已经能够使用相同语法来使用.join()方法匹配结果并返回它们,我认为它会返回行中的额外数据,因为它连接了表(也许我误解了该方法的工作方式或如何通过查询对象检索信息?)。
如果它有助于故障排除,我正在使用MySQL作为数据库
查询:
a = User.query.filter(User.user_id==1).join(UserGroup,
 User.usergroup==UserGroup.group_id).join(Areas, User.area==Areas.area_id).first()

还有表格:

class User(db.Model):
    user_id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), unique=True)
    usergroup = db.Column(db.Integer, db.ForeignKey('user_group.group_id'), nullable=False)
    area = db.Column(db.Integer, db.ForeignKey('areas.area_id'), nullable=False)

class UserGroups(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    group_id = db.Column(db.Integer, nullable=False, unique=True)
    group_name = db.Column(db.String(64), nullable=False, unique=True)


class Areas(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    area_id = db.Column(db.Integer, nullable=False, unique=True)
    area_name = db.Column(db.String(64), nullable=False, unique=True)
2个回答

6

看起来我需要使用不同的方法进行查询,它会返回一组对象元组,然后我需要解析它们。

可行的方法是:

 a = db.session.query(User, UserGroups, Areas
 ).filter(User.user_id==1
 ).join(UserGroup,User.usergroup==UserGroup.group_id
 ).join(Areas, User.area==Areas.area_id
 ).first()

其余部分保持不变。然后,它返回一个元组,我可以解析其中来自User的数据为a [0],来自UserGroups的数据为a [1],以及Areas为a [2]。然后,我可以使用a [1].group_name等来访问group_name列。

希望这能帮助其他试图使用此功能的人!


你是如何应用过滤器的? - alvirbismonte
1
Python支持\作为行继续符,这样你就不必每次都把带到下一行了。 - Carel

5
请看SQLAlchemy的relationship函数: http://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#one-to-many 你可能想在你的User类中添加一个新属性,如下所示:
group = sqlalchemy.relationship('UserGroups', back_populates='users')

这将自动解决UserUserGroups之间的一对多关系(假设一个用户只能是一个 UserGroup 的成员)。在从数据库查询用户(或一组用户)后,您可以轻松访问UserGroup的属性:

a = User.query.filter(...).first()
print(a.group.group_name)

SQLAlchemy会为您解决连接问题,查询时不需要显式地连接外部表。

反向访问也是可能的;如果您只查询UserGroup,您可以直接访问相应的成员(通过back_populates关键字参数):

g = UserGroup.query.filter(...).first()
for u in g.users:
    print(u.name)

2
我会尝试一下,但我仍然不完全理解ORM处理这些的方式,但这是我需要解决的问题,以便能够正确使用SQLAlchemy。目前我更熟悉连接操作,所以尽量坚持使用它。您上面的代码示例和链接为我提供了一个很好的起点,可以学习和探索ORM的属性和关系(我猜这使得所有这些变得更容易!) - Carl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接