簡體   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