以下MySQL查询可以使用单个SQLAlchemy session.query完成还是必须运行第二个session.query?如果是这样,怎么会这样?我可以在使用SQLAlchemy的查询中运行查询吗?
选择*,(从表2选择C其中id = table1.id)为d从表1其中foo = X
以下MySQL查询可以使用单个SQLAlchemy session.query完成还是必须运行第二个session.query?如果是这样,怎么会这样?我可以在使用SQLAlchemy的查询中运行查询吗?
选择*,(从表2选择C其中id = table1.id)为d从表1其中foo = X
你想要的是SQLAlchemy的的subquery
对象。本质上,您按照正常方式编写查询,但不是通过.all()
或.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 |
+------------+-------+-----|
(忽略可怕的数据库设计)
在这个例子中,我们希望得到一个包含所有的学生和他们的分数结果集,按年龄加入平均分数。在原始的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
结果应该是这样的:
+------------+-------+-----+---------+
| name | score | age | average |
+------------+-------+-----+---------+
| Xu Feng | 95 | 25 | 92 |
| John Smith | 88 | 26 | 87 |
| Sarah Taft | 89 | 25 | 92 |
| Ahmed Zaki | 86 | 26 | 87 |
+------------+-------+-----|---------+
在SQLAlchemy中,我们可以先定义自身的子查询:
from sqlalchemy.sql import func
avg_scores = (
session.query(
func.avg(StudentScores.score).label('average'),
StudentScores.age
)
.group_by(StudentScores.age)
.subquery()
)
现在我们的子查询被定义了,但是没有语句实际上被发送到数据库。不过,我们可以把我们的子查询的对象几乎好像它是另一个表中,写我们的主查询:
results = (
session.query(StudentScores, avg_scores)
.join(avg_scores, StudentScores.age == avg_scores.c.age)
.order_by('score DESC').all()
)
只不过现在是向数据库发出的任何SQL,并且我们得到了相同的结果生子查询例子。
话虽如此,你提供的例子实际上很平凡,根本不需要子查询。根据你的关系是如何定义的,SQLAlchemy的可热切负载相关的对象,从而使对象通过返回:
results = session.query(Table1).filter(Table1.foo == 'x').all()
将有从表2对该子女的探视(或父母)结果,即使我们没这里没有要求 - 因为直接在模型中定义的关系是为我们处理的。请查看SQLAlchemy文档中的"Relationship Loading Techniques"以获取更多关于它如何工作的信息。
什么OP后看起来像一个标量子查询,它[[Query.label()'](http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query。 Query.label)和['Query.as_scalar()'](http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.as_scalar)明确处理。 –