I have basic Flask application with Parent
and Child
models like that:
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)
As database I am using Postgres if it is important.
Now I want to do following: remove cascade='all,delete'
from child and make this parent_id
nullable. I.e. when Parent
removed from DB Child
stays in place with parent_id == NULL
.
I know that I could specify it with schema creation script adding constraint to FK. But I want just to mark it as NULL
and allow SqlAlchemy take control on nullification of children's FK.
It's explained in the relevant section of the documentation in a great detail. Make sure you also read "ORM-level “delete” cascade vs. FOREIGN KEY level “ON DELETE” cascade" section to understand differences between proposed solutions.
Now I want to do following: remove
cascade='all,delete'
from child and make thisparent_id
nullable.
Do it and you will get exact behaviour you want.
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)
Also note, that all
is the synonym for save-update, merge, refresh-expire, expunge, delete
, so all, delete
is the same as simply all
.
If you want to have ON DELETE SET NULL
constraint on the database level, you can specify ondelete='SET NULL'
in the ForeighKey
definition or do nothing (since it's default behaviour for the foreign key). To get it working on the DB level you also need to set passive_deletes
to either True
or 'all'
(see docs for the difference).
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With