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() 知道如何在 UserAddress 之间进行连接,因为我们设定了外键。假如我们没有指定外键,比如这样:

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之多表查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQL之多表查询

多表查询之多表查询的概述

数据库之多表查询

数据库之多表查询

mysql第四篇:数据操作之多表查询

MySQL之多表查询