我有基本的Flask应用程序Parent
和Child
类似的模型:
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无效.
它在文档的相关部分中进行了详细说明.确保您还阅读"ORM级别"删除"级联与外键级别"ON DELETE"级联"部分以了解建议的解决方案之间的差异.
现在我想做以下操作:
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_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)