以下 MySQL 查询可以使用单个 SQLAlchemy session.query 完成还是我必须运行第二个 session.query ?如果是这样,怎么会这样?
Select *, (select c from table2 where id = table1.id) as d from table1 where foo = x
你想要的是 SQLAlchemy 的subquery对象。本质上,您可以像往常一样编写查询,但不是以.all()or结束查询.first()(您通常会直接返回某种结果),而是.subquery()以返回子查询对象结束查询。子查询对象基本上生成嵌入在别名中的子查询 SQL,但不运行它。然后您可以在主查询中使用它,SQLAlchemy 将发出必要的 SQL 以在单个操作中执行查询和子查询。
假设我们有下student_scores表:
+------------+-------+-----+
| name | score | age |
+------------+-------+-----+
| Xu Feng | 95 | 25 |
| John Smith | 88 | 26 |
| Sarah Taft | 89 | 25 |
| Ahmed Zaki | 86 | 26 |
+------------+-------+-----|
Run Code Online (Sandbox Code Playgroud)
(忽略可怕的数据库设计)
在这个例子中,我们想要得到一个包含所有学生及其分数的结果集,并按年龄加入平均分数。在原始 SQL 中,我们会做这样的事情:
SELECT ss.name, ss.age, ss.score, sub.average
FROM student_scores AS "ss"
JOIN ( SELECT age, AVG(score) AS "average"
FROM student_scores
GROUP BY age) AS "sub"
ON ss.age = sub.age
ORDER BY ss.score DESC
Run Code Online (Sandbox Code Playgroud)
结果应该是这样的:
+------------+-------+-----+---------+
| name | score | age | average |
+------------+-------+-----+---------+
| Xu Feng | 95 | 25 | 92 |
| John Smith | 88 | 26 | 87 |
| Sarah Taft | 89 | 25 | 92 |
| Ahmed Zaki | 86 | 26 | 87 |
+------------+-------+-----|---------+
Run Code Online (Sandbox Code Playgroud)
在 SQLAlchemy 中,我们可以先自己定义子查询:
from sqlalchemy.sql import func
avg_scores = (
session.query(
func.avg(StudentScores.score).label('average'),
StudentScores.age
)
.group_by(StudentScores.age)
.subquery()
)
Run Code Online (Sandbox Code Playgroud)
现在我们的子查询已经定义,但实际上没有语句被发送到数据库。尽管如此,我们几乎可以将我们的子查询对象视为另一个表,并编写我们的主查询:
results = (
session.query(StudentScores, avg_scores)
.join(avg_scores, StudentScores.age == avg_scores.c.age)
.order_by('score DESC').all()
)
Run Code Online (Sandbox Code Playgroud)
现在才向数据库发出任何 SQL,我们得到与原始子查询示例相同的结果。
话虽如此,您提供的示例实际上非常简单,根本不需要子查询。根据关系的定义方式,SQLAlchemy 可以急切地加载相关对象,以便通过以下方式返回对象:
results = session.query(Table1).filter(Table1.foo == 'x').all()
Run Code Online (Sandbox Code Playgroud)
将可以访问 Table2 中的子(或父)记录,即使我们在这里没有要求它 - 因为直接在模型中定义的关系正在为我们处理。查看SQLAlchemy 文档中的“关系加载技术”以获取有关其工作原理的更多信息。
| 归档时间: |
|
| 查看次数: |
5007 次 |
| 最近记录: |