【问题标题】:SQLAlchemy many-to-many relationship deletion operation on one sideSQLAlchemy 一侧的多对多关系删除操作
【发布时间】:2021-10-27 06:34:57
【问题描述】:

我有一个由关联表链接的多对多关系,如下所示:

left_right_association_table = Table("left_right_association_table", Base.metadata,
        Column('leftside_id', Integer, ForeignKey('leftside_table.id')),
        Column('rightside_id', Integer, ForeignKey('rightside_table.id'))
    )

class LeftSide(Base):
    ...
    rightside_members = relationship("RightSide", secondary=left_right_association_table, backref="leftside", lazy="joined")
    ...


class RightSide(Base):
    ...

现在我有一个LeftSide 实例,其中RightSide 实例的list 作为其rightside_members 属性:

ls = LeftSide(**kw)
rs1 = RightSide(**kw)
rs2 = RightSide(**kw)
ls.rightside_members.append(rs1)
ls.rightside_members.append(rs2)

然后,我想删除列表成员之一:rs2

第 1 步:我重现 rightside_members 列表:

updated_rightside_members = [RightSide(**rs_attrs) for rs_attrs in ls.rightside_members] # each `rs` object already has primary key
updated_rightside_members.pop() # remove the second item from the list

第 2 步:我从数据库中检索 ls

old_ls = db_session.query(LeftSide).filter(LeftSide_id == ls.id).one()

第 3 步:我将 updated_rightside_members 添加到 old_ls

old_ls.rightside_members = updated_rightside_members

第 4 步:提交到数据库。

db_session.commit()

然后我得到这个错误:

sqlite3.IntegrityError: UNIQUE constraint failed: rightside_table.id

在我看来,SQLAlchemy 认为我正在尝试将重复的 rs1 放回数据库,而不是从数据库中删除其兄弟 rs2

这个删除操作应该怎么做?

【问题讨论】:

  • edit您的问题表明您是如何从关系中删除该项目的。 FWIW,this code 对我来说很好。
  • @GordThompson 是的,你完全正确。我刚刚编辑了我的步骤。

标签: sqlalchemy many-to-many


【解决方案1】:

我已经解决了这个问题。首先,我真的想指出仔细阅读文档会有所帮助。使用映射类来初始化一个实例并不意味着会话知道这个对象,至少在你使用Session.add() 方法之前是这样。

所以,正确的步骤应该是这样的:

  1. 决定传入的参数是否包含代表实例主键的id。如果是这样,那么正确的做法是从数据库中查询它,而不是初始化它。这样Session 将确保查询的对象在其identity map 中具有唯一的对象ID。
  2. 如果它不包含id 属性,则对其进行初始化,并将其添加到成员列表中。

【讨论】:

  • 是的。本质上,您是在创建新的 RightSide 对象(通过RightSide(**rs_attrs)),而不是对会话知道的现有 RightSide 对象进行操作。我的示例代码有效,因为我在现有 RightSide 对象列表上进行操作,因此会话能够跟踪它们。
猜你喜欢
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多