2

I'd like to add some custom behavior to some SQLALchemy models when they are deleted, e.g. when a User is deleted, all his Posts are deleted too (easy to do using cascade), but I'd like to call a custom routine on each of those Posts when they are deleted.

class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    posts = db.relationship('Post', back_populates='user', cascade="save-update, merge, delete, delete-orphan")


class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    text = db.Column(db.String(140))
    filename = db.Column(db.String(60))

    user = db.relationship('User', back_populates='posts')

Let's say I delete a user with db.session.delete(user) and I commit this, I'd like a function to be called automatically for each related Post to remove the file post.filename, so that after this db.session.delete(user) and commit, all local files related to all user's posts are removed.

Ideally it would perfect just to have to add a method in the Post class that is called automatically when a post is marked for deletion. Something like:

class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    text = db.Column(db.String(140))
    filename = db.Column(db.String(60))

    user = db.relationship('User', back_populates='posts')

    def on_delete(self):
        os.remove(self.filename)

I insist on the fact that this on_delete method should be called automatically when a post is marked for deletion. Is it possible to achieve such a result?

regu
  • 55
  • 8
  • Maybe registering a handler to the [persistent_to_deleted](https://docs.sqlalchemy.org/en/13/orm/events.html#sqlalchemy.orm.events.SessionEvents.persistent_to_deleted) event? – SuperShoot Aug 29 '19 at 10:42
  • Thanks for your answer. `persistent_to_deleted` event didn't do the job, but the `after_delete` one works perfectly. Thank for your help ! :) – regu Aug 30 '19 at 09:02
  • Glad you worked it out! – SuperShoot Aug 30 '19 at 09:13

0 Answers0