sqlalchemy

SQLAlchemy throwing integrity error, "update or delete on table violates foreign key constraint"


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:

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


Solution

  • 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
               )