如何从 SqlAlchemy 中的多对多集合中删除所有项目?
Posted
技术标签:
【中文标题】如何从 SqlAlchemy 中的多对多集合中删除所有项目?【英文标题】:How to remove all items from many-to-many collection in SqlAlchemy? 【发布时间】:2011-12-14 21:23:18 【问题描述】:当我需要从声明性 ORM 多对多关系中删除对象时,我应该这样做:
blogpost.tags.remove(tag)
嗯。如果我需要清除所有这些关系(不仅仅是一个),我应该怎么做?典型情况:我想为我的博文设置一个新的标签列表。所以我需要...:
-
删除该博文和标签之间的所有现有关系。
设置新关系并在不存在时创建新标签。
当然,可能有更好的方法来做到这一点。在这种情况下,请告诉我。
【问题讨论】:
【参考方案1】:这是清除列表的标准 Python 习语——分配给“整个列表”切片:
blogpost.tags[:] = []
您可能希望直接分配新的标签集,而不是空列表。
blogpost.tags[:] = new_tags
SQLAlchemy 的关系是instrumented attributes,这意味着它们保留了列表(或集合、字典等)的接口,但任何更改都会反映在数据库中。这意味着您可以对列表执行的任何操作都可以通过关系实现,而 SQLA 透明地侦听更改并相应地更新数据库。
【讨论】:
或者换一种说法:SQLAlchemy 很棒。 为什么不只是blogpost.tags = new_tags
? (不带 [:])
当我现在尝试这个时(2014 年 12 月,SQLAlchemy 0.9)我得到“TypeError: 'AppenderBaseQuery' 对象不支持项目分配。”
我花了很长时间在谷歌搜索“SQLAlchemy 如何替换所有关系元素”。在这里评论,希望有助于简化搜索。 @Devi 这不起作用。您将用新类型(列表)替换 sqla Collection 对象
随着图书馆在版本/年中的演变,许多事情必须发生变化,并且接受和一旦工作的答案现在可能不起作用。 Q 和 A 中的版本最好是精确的。【参考方案2】:
确认Two-Bit Alchemist 报告的内容。
blogpost.tags[:] = new_tags
会抱怨
TypeError: 'AppenderBaseQuery' object does not support item assignment
但是
blogpost.tags = new_tags
似乎工作正常。
【讨论】:
这不会将任何内容保存到数据库中,这意味着设置为空列表不会清除记录 @kevlarr 这确实有效,因为blogpost
对象的tags
字段也被检测;当您为其分配一个空列表时,该空列表将替换为一个空的sqlalchemy.orm.dynamic.AppenderBaseQuery
对象。
@Tom 如果是版本问题,我会很好奇,因为我已经尝试过,结果与您报告的结果不同。不过,我无法再访问代码,所以不确定我使用的是什么版本(在我发表评论时它应该是最新的)。您确定空列表的分配实际上删除了数据库记录?以上是关于如何从 SqlAlchemy 中的多对多集合中删除所有项目?的主要内容,如果未能解决你的问题,请参考以下文章