gpt4 book ai didi

python - 在 SQLAlchemy 中删除左外连接右侧的 NULL

转载 作者:太空宇宙 更新时间:2023-11-03 15:21:01 25 4
gpt4 key购买 nike

我有一个Track 表和一个Artist 表。 Artist 表有一个 idTrack 表有一个外键,artist_id。我想删除所有没有关联轨道的艺术家。

在 SQL 中:

delete from artists 
where id in (select artists.id
from artists left outer join tracks
on tracks.artist_id = artists.id
where tracks.id is null);

效果很好。但是当我尝试在 SQLAlchemy 中复制它时:

artists = session.query(Artist.id).outerjoin((Track, Artist.id == Track.artist_id)).filter(Track.id == None)
print('deleting %d unused artists' % artists.count())
session.query(Artist).filter(Artist.id.in_(artists.all())).delete()

print() 工作正常(并显示正确的行数)但删除给出了错误:

...
sqlalchemy.orm.evaluator.UnevaluatableError: Cannot evaluate clauselist with operator <function comma_op at 0x2d3e0d8>
During handling of the above exception, another exception occurred:
...
"Could not evaluate current criteria in Python. "
sqlalchemy.exc.InvalidRequestError: Could not evaluate current criteria in Python. Specify 'fetch' or False for the synchronize_session parameter.

那么我如何在 SQLAlchemy 中执行此操作?我不介意方法是否不同,只要我可以删除不属于任何轨道的所有艺术家。

PS 我还尝试了 artists.delete()(同时选择 Artist 实例,而不是上面的 id)这也给出了一个错误 - 在这种情况下,外部连接“丢失”并且SQL 不一致。

更新

万一这对任何人都有用,如果您的模型中有一个 backref(artists,如下),则有一种比外部连接更简单的方法:

session.query(Artist).filter(Artist.tracks == None).delete(synchronize_session=False)

最佳答案

异常是告诉你如何解决这个问题,你需要指定一个 synchronize_session 作为 "fetch"False 之一. Sqlalchemy 试图通过更新附加到 session 的对象的状态来避免做一些额外的工作,以通过直接将删除应用于 python 对象来反射(reflect)数据库中的更改。

不幸的是,它无法为该查询执行此操作,因此您需要告诉它“获取”事件的 Artist 以查看它们是否已被删除,或者只是忽略它,并使 session 处于无效状态。

您还会在 in_(query.all()) 产生过程中遇到问题;因为 sqlalchemy 不知道如何绑定(bind)元组的列表,并且也是对原始查询的不完美再现。只需 in_(query) 就足够了。

关于python - 在 SQLAlchemy 中删除左外连接右侧的 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14929061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com