I am trying to set-up a cascade delete on a join relationship. However, whenever I try to delete a post in my application, I receive an error saying that, "update or delete on table "post" violates foreign key constraint" Here is a photo of the error message:
Here is my code:
class Post(db.Model):
"""Blog posts"""
__tablename__ = "posts"
id = db.Column(db.Integer,
primary_key=True,
autoincrement=True)
title = db.Column(db.String(25),
nullable=False)
content = db.Column(db.String(500),
nullable=False)
created_at = db.Column(db.DateTime,
default=db.func.current_timestamp())
user_table = db.Column(db.Integer,
db.ForeignKey('users.id',
ondelete='CASCADE'))
tags = db.relationship('Tag',
secondary="post_tags",
back_populates="posts",
cascade="all, delete"
)
class Tag(db.Model):
__tablename__ = "tags"
id = db.Column(db.Integer,
primary_key=True,
autoincrement=True)
name = db.Column(db.String,
unique=True)
posts = db.relationship('Post',
secondary="post_tags",
back_populates="tags")
class Post_Tag(db.Model):
__tablename__ = "post_tags"
post_id = db.Column(db.Integer,
db.ForeignKey('posts.id'), primary_key=True)
tag_id = db.Column(db.Integer,
db.ForeignKey('tags.id'), primary_key=True)
Based on the documentation and other questions I've viewed, I seem to be setting this up correctly. What am I doing wrong here?
UPDATE I can delete Tags, but cannot delete Posts
You may be recieving this error because you're using backref
instead of back_populates
...
Also, I'd suggest defining your relationship bidirectionally, meaning in both the parent Post
and child Tag
models. This allows cascade deletion to the secondary table with different rules depending on which object is being deleted.
The following changes to your models should fix the error you're receiving:
# Modify your tags relationship to the following:
class Post(db.Model):
...
tags = db.relationship(
'Tag',
secondary="post_tags",
back_populates="posts", # use back-populates instead of backref
cascade="all, delete"
)
# Also, define your relationship from your tag model
class Tag(db.Model):
__tablename__ = "tags"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String, unique=True)
posts = db.relationship(
'Post',
secondary="post_tags",
back_populates="tags", # use back-populates instead of backref
# When a parent ("post") is deleted, don't delete the tags...
passive_deletes=True
)