flask_SQLALchemy之多表查询
Posted moying-wq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask_SQLALchemy之多表查询相关的知识,希望对你有一定的参考价值。
1. join 查询
假设这样一个业务场景,知道一个邮箱地址,要查询这个地址所属的用户,第一个办法是用连接多个 filter()
来查询。
for u, a in session.query(User, Address).filter(User.id==Address.user_id).filter(Address.email_address==‘[email protected]‘).all(): print(u) print(a) # 执行结果 jack [email protected]
更简便的方法是使用 join()
方法:
u = session.query(User).join(Address).filter(Address.email_address==‘[email protected]‘).one() print(u) # 执行结果 jack
Query.join()
知道如何在 User
和 Address
之间进行连接,因为我们设定了外键。假如我们没有指定外键,比如这样:
class User(Base): __tablename__ = ‘users‘ id = Column(Integer, primary_key=True) name = Column(String(50)) fullname = Column(String(50)) password = Column(String(12)) class Address(Base): __tablename__ = ‘addresses‘ id = Column(Integer, primary_key=True) email_address = Column(String, nullable=False) user_id = Column(Integer)
我们可以用下面方法来让 join
生效:
query.join(Address, User.id==Address.user_id) # explicit condition query.join(User.addresses) # specify relationship from left to right query.join(Address, User.addresses) # same, with explicit target query.join(‘addresses‘) # same, using a string
例子:
session.query(User).join(Address, User.id==Address.user_id).filter(Address.email_address==‘[email protected]‘).all()
2. 子查询(subquery)
现在需要查询每个用户所拥有的邮箱地址数量,思路是先对 addresses 表按用户 ID 分组,统计各组数量,这样我们得到一张新表;然后用 JOIN 连接新表和 users 两个表,在这里,我们应该使用 LEFT OUTER JOIN,因为使用 INTER JOIN 所得出的新表只包含两表的交集。
如果上面的暂时看不懂,我们先来看看第一个 stmt 的情况。
from sqlalchemy.sql import func stmt = session.query(Address.user_id, func.count(‘*‘).label(‘address_count‘)).group_by(Address.user_id).all() for i in stmt: print(i) # 执行结果 (5, 2)
可以理解成 group_by()
方法生成了一张新的表,该表有两列,第一列是 user_id ,第二列是该 user_id 所拥有的 addresses 的数量,这个值由 func()
跟着的方法产生,我们可以使用 c()
方法来访问这个值。
from sqlalchemy.sql import func stmt = session.query(Address.user_id, func.count(‘*‘).label(‘address_count‘)).group_by(Address.user_id).subquery() q = session.query(User, stmt.c.address_count).outerjoin(stmt, User.id==stmt.c.user_id).order_by(User.id).all() for i in q: print(i) # 执行结果 (ed, None) (wendy, None) (mary, None) (fred, None) (jack, 2)
如果不用 outerjoin()
而使用 join()
,就等于使用 SQL 中的 INTER JOIN,所得出的表只为两者交集,不会包含 None 值的列。
from sqlalchemy.sql import func stmt = session.query(Address.user_id, func.count(‘*‘).label(‘address_count‘)).group_by(Address.user_id).subquery() q = session.query(User, stmt.c.address_count).join(stmt, User.id==stmt.c.user_id).order_by(User.id).all() for i in q: print(i) # 执行结果 (jack, 2)
以上是关于flask_SQLALchemy之多表查询的主要内容,如果未能解决你的问题,请参考以下文章