当前位置:  开发笔记 > 编程语言 > 正文

如何在使用sqlalchemy删除父项时使childre的外键无效?

如何解决《如何在使用sqlalchemy删除父项时使childre的外键无效?》经验,为你挑选了1个好方法。

我有基本的Flask应用程序ParentChild类似的模型:

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空.即Parent从数据库Child中删除时保留到位parent_id == NULL.

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



1> Yaroslav Adm..:

它在文档的相关部分中进行了详细说明.确保您还阅读"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)

另请注意,这all是同义词save-update, merge, refresh-expire, expunge, delete,因此all, delete与简单相同all.

数据库级别

如果要对ON DELETE SET NULL数据库级别进行约束,可以ondelete='SET NULL'ForeighKey定义中指定或不执行任何操作(因为它是外键的默认行为).要使其在数据库级别上运行,您还需要设置passive_deletesTrue'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)

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有