SQLAlchemy Join 从多个表中检索数据

Car*_*arl 8 python mysql sqlalchemy

我正在尝试使用.join()方法使用SQLAlchemy从多个表中检索数据。

当我运行查询时,我期望返回一个对象,该对象包含连接的不同表中的所有数据,以便我可以使用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()
Run Code Online (Sandbox Code Playgroud)

和表格:

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)
Run Code Online (Sandbox Code Playgroud)

Car*_*arl 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()
Run Code Online (Sandbox Code Playgroud)

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

希望这对尝试处理此问题的其他人有所帮助!


jbn*_*dlr 5

看一下SQLAlchemy的relationship函数:

http://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#one-to-many

您可能想向您的类添加一个新属性,User如下所示:

group = sqlalchemy.relationship('UserGroups', back_populates='users')
Run Code Online (Sandbox Code Playgroud)

User这将自动解析和之间的一对多关系UserGroups(假设用户一次只能是一个用户组的成员)。一旦从数据库中查询了一个用户(或一组用户),您就可以简单地访问用户组的属性:

a = User.query.filter(...).first()
print(a.group.group_name)
Run Code Online (Sandbox Code Playgroud)

SQLAlchemy 会为您解决联接问题,您在查询时无需显式联接外表。

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

g = UserGroup.query.filter(...).first()
for u in g.users:
    print(u.name)
Run Code Online (Sandbox Code Playgroud)

  • 我会尝试一下,仍然不完全理解 ORM 处理这些的方式,但无论如何我都需要修复这个问题才能正确使用 SQLAlchemy。目前我对连接更加熟悉,所以尝试坚持这一点。上面的代码示例和链接为我提供了一个开始学习和探索 ORM 属性和关系的好地方(我猜这会让这一切变得更容易!) (2认同)