【问题标题】:How to nullify childre's foreign key when parent deleted using sqlalchemy?使用sqlalchemy删除父级时如何使子级的外键无效?
【发布时间】:2016-04-02 13:20:49
【问题描述】:

我有 ParentChild 这样的基本 Flask 应用程序:

class Parent(db.Model):
    __tablename__ = 'parents'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)


class Child(db.Model):
    __tablename__ = 'children'

    id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('parents.id'), nullable=False)
    parent = db.relationship('Parent', backref=db.backref('children', cascade='all,delete'))
    name = db.Column(db.String)

如果重要的话,我会使用 Postgres 作为数据库。 现在我想做以下事情:从孩子中删除 cascade='all,delete' 并使这个 parent_id 可以为空。 IE。当 Parent 从 DB 中删除时,Childparent_id == NULL 保持一致。

我知道我可以使用模式创建脚本来指定它,将约束添加到 FK。但我只想将其标记为 NULL 并允许 SqlAlchemy 控制儿童 FK 的无效。

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    在文档的relevant section 中有详细的解释。确保您还阅读了“ORM 级“删除”级联与外键级“ON DELETE”级联”部分,以了解建议的解决方案之间的差异。

    ORM 级别

    现在我想做以下事情:从孩子中删除 cascade='all,delete' 并使这个 parent_id 可以为空。

    这样做,你会得到你想要的确切行为。

    class Child(db.Model):
        __tablename__ = 'children'
    
        id = db.Column(db.Integer, primary_key=True)
        parent_id = db.Column(db.Integer, db.ForeignKey('parents.id'), nullable=True)
        parent = db.relationship('Parent', backref=db.backref('children'))
        name = db.Column(db.String)
    

    另请注意,allsave-update, merge, refresh-expire, expunge, delete 的同义词,因此 all, delete 与简单的 all 相同。

    数据库级别

    如果你想在数据库级别有ON DELETE SET NULL 约束,你可以在ForeighKey 定义中指定ondelete='SET NULL' 或者什么都不做(因为它是外键的默认行为)。要使其在 DB 级别上运行,您还需要将 passive_deletes 设置为 True'all'(请参阅文档了解差异)。

    class Child(db.Model):
        __tablename__ = 'children'
    
        id = db.Column(db.Integer, primary_key=True)
        parent_id = db.Column(db.Integer, db.ForeignKey('parents.id', ondelete='SET NULL'), nullable=True)
        parent = db.relationship('Parent', backref=db.backref('children', passive_deletes=True))
        name = db.Column(db.String)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-29
      • 2019-12-24
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      • 1970-01-01
      • 2018-11-07
      • 1970-01-01
      相关资源
      最近更新 更多