【问题标题】:Prevent parent deletion with SQLAlchemy backref使用 SQLAlchemy backref 防止父删除
【发布时间】:2017-06-30 10:09:00
【问题描述】:

我有一个组织模型:

class Organization(SharedModel):
    name = db.Column(db.String(200), nullable=False)

以及像这样反向引用Organization的几个模型:

class OrganizationBusinessLine(db.Model):
     organization_id = db.Column(db.Integer, db.ForeignKey('organization.id'), nullable=False)
     organization = db.relationship('Organization', foreign_keys=[organization_id],
                               single_parent=True,
                               backref=db.backref('businessLines', uselist=True))

     name = db.Column(db.String(200), nullable=False)

Organization 被删除时,我希望与组织关联的所有OrganizationBusinessLines 都被删除,这很好用:

def test_that_children_of_organization_are_deleted(session)
    organization_id = 1
    organization = session.query(Organization).get(organization_id)
    business_line_ids = [instance.id for instance in
                         session.query(OrganizationBusinessLine).filter_by(organization=organization).all()]

    db.session.delete(instance)
    db.session.commit()
    for instance_id in business_line_ids:
        assert session.query(OrganizationBusinessLine).get(instance_id) is None

但是当我删除一条业务线时,关联的组织也会被删除:

def test_that_parent_is_not_deleted(session):
    business_line = session.query(OrganizationBusinessLine).first()

    business_line_id = business_line.id
    organization_id = business_line.organization_id

    OrganizationBusinessLine.delete(business_line_id)

    assert session.query(OrganizationBusinessLine).get(business_line_id) is None
    assert session.query(Organization).get(organization_id) is not None # Fails

我在backref 上尝试了几个不同的cascade=-options,但我无法让“父”(Organization)不被删除。

backrefs 的默认cascade= 选项是according to the docs

级联的默认行为仅限于所谓的保存更新和合并设置的级联。

我希望这些设置甚至不会删除“子”对象,但它似乎可以。

如果这很重要,我正在本地 SQLite 数据库上运行测试。

【问题讨论】:

  • 请贴出OrganizationBusinessLine.delete的定义。

标签: python sqlalchemy


【解决方案1】:

使用父类的关系并使用 ondelete=CASCADE 引用父外键:

class Organization(SharedModel):
    name = db.Column(db.String(200), nullable=False)
    businneslines = relationship(
        'Component',
        backref=backref("organization"),
        cascade="all,delete"
    )

class OrganizationBusinessLine(db.Model):
    organization_id = db.Column(db.Integer,
                                db.ForeignKey('organization.id'), 
                                nullable=False)
    organization_id =  Column(
        Integer,
        ForeignKey('organization.id', ondelete='CASCADE'))

【讨论】:

    猜你喜欢
    • 2017-11-16
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多