繁体   English   中英

SQLAlchemy:在子查询中使用外部查询中的列

[英]SQLAlchemy: Use column from outer query in subquery

我的问题

我有这个(MSSQL)查询,我想将其转换为SQLAlchemy:

SELECT * FROM Artikel AS root WHERE (SELECT COUNT(*) FROM Artikel WHERE Artikel.MM_ParentID = root.ROW_ID) = 0 AND MM_ParentID = 0;

这是我尝试的:

root = sqlalchemy.orm.aliased(GSDArtikel, name='root')
parent_count_query = gsd_session.query(sqla.func.count()).select_from(GSDArtikel).filter(GSDArtikel.MM_ParentID == root.row_id)
results = gsd_session.query(root).filter((parent_count_query == 0) & (root.MM_ParentID == 0))

但是, parent_count_query == 0生成布尔值,这将导致失败:

TypeError: unsupported operand type(s) for &: 'bool' and 'BinaryExpression'

parent_count_query有型sqlalchemy.orm.query.Query

我也尝试添加.subquery()这类型更改为sqlalchemy.sql.selectable.Alias ,但还是给了我False的比较时。

当我打印生成的内部查询时,它看起来不太像我期望的那样:

SELECT count(*) AS count_1 
FROM [Artikel], [Artikel] AS root 
WHERE [Artikel].[MM_ParentID] = root.row_id

我也尝试使用sqla.and_(parent_count_query == 0, root.MM_ParentID == 0)代替& -然后我没有得到TypeError ,而是得到以下SQL以获得results

SELECT ...
FROM [Artikel] AS root 
WHERE 0 = 1

我究竟做错了什么?

大图景

我有一个带有根行和子行的表,基本上是这样的:

| row_id | MM_ParentID |
------------------------
| 1      | 0           |
| 2      | 0           |
| 3      | 0           |
| 4      | 1           |
| 5      | 1           |
| 6      | 3           |

我想找到的是所有属于父级( MM_ParentID == 0 )并且没有子级的行(子查询将获得所有MM_ParentID等于当前项的row_id的子级的子查询返回0行)。 因此,在这种情况下,将返回具有row_id 2的项目。

您的问题是您无法在sqlalchemy构建子查询,然后只能像在纯SQL那样比较结果。

无论如何,如果我正确理解了您的问题,我会以其他方式解决它; 首先获取确实有父母的文章,

In [39]:
from sqlalchemy.orm import aliased
root = aliased(Article, name='root')
subq = session.query(Article.id).select_from(Article).filter(Article.parent_id == root.id)
print(subq)

SELECT article.id AS article_id 
FROM article, article AS root 
WHERE article.parent_id = root.id

然后寻找像这样的基础文章:

In [40]:
from sqlalchemy import tuple_
results = session.query(Article).filter(~Article.id.in_(subq))
print(results)

SELECT article.id AS article_id, article.parent_id AS article_parent_id 
FROM article 
WHERE article.id NOT IN (SELECT article.id AS article_id 
FROM article AS root 
WHERE article.parent_id = root.id)

当然,还有其他方法。 这是我想出的简单方法,如果您的桌子很大,可能不是最佳选择。 (很抱歉,我为您的表名和列名使用了不同的拼写!)

希望能帮助到你。

我最终简化了查询,以便将孩子与父母联系起来,然后得到孩子为IS NULL的孩子:

stray_parents = (gsd_session.query(item)
                 .outerjoin(child, item.row_id == child.MM_ParentID)
                 .filter(item.MM_ParentID == 0, child.row_id == None))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM