【问题标题】:How to remove all items from many-to-many collection in SqlAlchemy?如何从 SqlAlchemy 中的多对多集合中删除所有项目?
【发布时间】:2011-12-14 21:23:18
【问题描述】:

当我需要从声明性 ORM 多对多关系中删除对象时,我应该这样做:

blogpost.tags.remove(tag)

嗯。如果我需要清除所有这些关系(不仅仅是一个),我应该怎么做?典型情况:我想为我的博文设置一个新的标签列表。所以我需要...:

  1. 删除该博文和标签之间的所有现有关系。
  2. 设置新关系并在不存在时创建新标签。

当然,可能有更好的方法来做到这一点。在这种情况下,请告诉我。

【问题讨论】:

    标签: python many-to-many sqlalchemy


    【解决方案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 如果是版本问题,我会很好奇,因为我已经尝试过,结果与您报告的结果不同。不过,我无法再访问代码,所以不确定我使用的是什么版本(在我发表评论时它应该是最新的)。您确定空列表的分配实际上删除了数据库记录?
    猜你喜欢
    • 1970-01-01
    • 2018-02-02
    • 2021-04-02
    • 1970-01-01
    • 2015-02-28
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    相关资源
    最近更新 更多