我有这个(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
会生成一个bool,这会导致失败:
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
,而是为results
获取以下SQL:
SELECT ...
FROM [Artikel] AS root
WHERE 0 = 1
我做错了什么?
我有一个包含root和children行的表,基本上看起来像这样:
| row_id | MM_ParentID |
------------------------
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 1 |
| 5 | 1 |
| 6 | 3 |
我想要找到的是所有父级(MM_ParentID == 0
)并且没有子级的子行(子查询会使MM_ParentID
的所有子级等于当前的row_id
item返回0行)。因此,在这种情况下,将返回row_id
2的项目。
答案 0 :(得分:0)
您的问题是您无法在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)
当然还有其他方法;这是我发现的更简单,如果你的桌子非常大,可能不是最佳的。 (对不起,我已经为你的表名和列名使用了不同的拼写!)
希望它有所帮助。
答案 1 :(得分:0)
我最终简化了查询,因此它将孩子与父母联系起来,然后得到孩子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))