0

You are able to delete all children after their associate parent gets deleted cascadingly, but what about the opposite way? In this many-to-one relationship:

class RecipeTag(db.Model):

    __tablename__ = "recipe_tags"
    id = db.Column(db.Integer, primary_key=True)
    recipe_id = db.Column(db.Integer, db.ForeignKey("recipes.id", ondelete="CASCADE"), nullable=False)
    tag_id = db.Column(db.Integer, db.ForeignKey("tags.id", ondelete="CASCADE"), nullable=False)

    parent = db.relationship("Tag", cascade="all, delete", single_parent=True, back_populates="children")

class Tag(db.Model):

    __tablename__  = "tags"
    id = db.Column(db.Integer, primary_key=True)
    tag = db.Column(db.String, nullable=False)

    children = db.relationship("RecipeTag", cascade="all, delete, delete-orphan", back_populates="parent")

The RecipeTag will connect the Recipe model with the Tag model via foreign keys. However, many recipes will use the same tag, thus a Tag can have multiple references from RecipeTag. So when a recipe gets deleted, all its associated recipe_tags get deleted as well automatically through cascade deletes, leaving some tags to be childless. So it doesn't need to exist anymore.

I was thinking of querying all of the tags and pick ones out that have no children left like so:

class Tag(db.Model):
    ...
    @staticmethod
    def delete_after_no_children():
        tags = Tag.query.all()
        for tag in tags:
            if not tag.children:
                db.session.delete(tag)
        db.session.commit()

This works, but I think it would be wildly inefficient. What would be the best approach to do this?

jarlh
  • 42,561
  • 8
  • 45
  • 63
Vaiterius
  • 45
  • 6
  • 1
    related: https://stackoverflow.com/a/64401347/2144390 – Gord Thompson Aug 13 '22 at 21:06
  • I guess a listener would be one way to go at it, though I was expecting there would be some sort of query or model statement that I wasn't aware of. The other answers there seem good to try. – Vaiterius Aug 14 '22 at 05:59

0 Answers0