在sqlalchemy中删除所有子对象时删除父对象

2024-06-26 02:13:27 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有以下关系:

{cda}和{cda}的关联是slide。在

一张幻灯片可以在许多引用中使用(使用不同的组):主键是slide_id+group_id,它必须是唯一的。在

我想在删除指向组或幻灯片时删除所有引用。 我在关系的backref中添加了一个级联:

# definition of Reference model

slide = db.relationship(
    Slide,
    backref=db.backref('references', cascade='all, delete, delete-orphan')
)

group = db.relationship(
    Group,
    backref=db.backref('references', cascade='all, delete, delete-orphan')
)

我还想删除被引用的组或幻灯片,只要我删除引用,并且没有其他引用使用该组和/或幻灯片。在

我考虑过在需要时使用@listens_for(Reference, 'after_delete')手动删除父项。我也尝试过属性组合在关系中,但我不确定如何解决这个问题。在


Tags: iddb关系groupalldeletecascadereference
1条回答
网友
1楼 · 发布于 2024-06-26 02:13:27

我认为用^{}的主意不错。你只需要听一下Reference^{}。下面是一个可以帮助您的例子。在

class Slide(db.Model):
    __tablename__ = 'slide'

    id = db.Column(db.Integer, primary_key=True)
    children = db.relationship('Reference')
    references = db.relationship('Reference', back_populates='slide')


class Group(db.Model):
    __tablename__ = 'group'

    id = db.Column(db.Integer, primary_key=True)
    references = db.relationship('Reference', back_populates='group')


class Reference(db.Model):
    __tablename__ = 'reference'

    id = db.Column(db.Integer, primary_key=True)
    slide_id = db.Column(db.Integer, db.ForeignKey('slide.id'))
    group_id = db.Column(db.Integer, db.ForeignKey('group.id'))
    group = db.relationship('Group', back_populates='references')
    slide = db.relationship('Slide', back_populates='references')


@event.listens_for(Reference, 'before_delete')
def delete_reference(mapper, connection, target):
    # after_flush used for consistent results
    @event.listens_for(Session, 'after_flush', once=True)
    def receive_after_flush(session, context):
        # just do here everything what you need...
        # if our preference slide is the last one
        if target.slide and not target.slide.references:
            print('add slide with id = %s to delete' % target.slide.id)
            session.delete(target.slide)
        # if our preference group is the last one
        if target.group and not target.group.references:
            session.delete(target.group)
            print('add group with id = %s to delete' % target.group.id)

让我们检查一下:

^{pr2}$

您将看到在第一种情况下,PreferenceGroup和{}被删除。因为其他的PreferenceGroup和{}无关。但在第二种情况下,您将看到只有Preference被删除:

reference with id 76 was created. slide_id = 65, group_id = 65
add reference with id = 76 to delete
add slide with id = 65 to delete
add group with id = 65 to delete
amount references after delete: []
reference with id 77 was created. slide_id = 66, group_id = 66
reference2 with id 78 was created. slide_id = 66, group_id = 66
add reference with id = 77 to delete
# with slide_id = 66, group_id = 66
amount references after delete: [<Reference 78>]

希望这有帮助。在

相关问题 更多 >