- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个Track
表和一个Artist
表。 Artist
表有一个 id
,Track
表有一个外键,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/
我知道除了知道什么是“最喜欢的编程卡通”之外,stackoverflow 会对我有所帮助:P 这是接受的答案: Bill Karwin 感谢大家的帮助(我想给你们加倍投票) 我的查询结果是这样的(这是
我查询了此查询,该查询将相关图像返回到评论 return $comments = \DB::table('comments')->select('comments.comment','com
如果没有任何地址(内部连接),我有以下 LINQ 返回零。我如何将其设为 Outer Join 然后仅 Take(1)? var results = query.Join(
我是一名优秀的程序员,十分优秀!