'Deleting object in a (SQLAlchemy) many-to-many relationship (works in sqlite but fails when using postgres)?

I seem to hit an issue when trying to delete an object from a many-to-many relation that seems to work with sqlite, but fails on postgres.

Any help or hint is highly appreciated!

This part is the code fails when using postgres.

# try to delete group 1
session.query(Group).filter_by(name="group 1").delete()

Example code:

Many to many example:
An Item can belong to many groups and a Group can contain many items

Is it possible to delete a group containing a number of items without
a need to set the Group.items collection to [] and still keep all the items?
from sqlalchemy import Column, Integer, String, Table, ForeignKey, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship

from testcontainers.postgres import PostgresContainer


Base = declarative_base()

item_group_members = Table('item_group_members', Base.metadata,
    Column('group_id', ForeignKey('group.id'), primary_key=True),
    Column('item_id', ForeignKey('item.id'), primary_key=True)
)

class Group(Base):
    __tablename__ = 'group'

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, unique=True, nullable=False)

    # relationships
    items = relationship("Item", secondary=item_group_members, back_populates="groups")

class Item(Base):
    __tablename__ = 'item'

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, unique=False, nullable=False)

    # relationships
    groups = relationship("Group", secondary=item_group_members, back_populates="items")

def run(connection_url):
    engine = create_engine(connection_url)
    Base.metadata.create_all(engine)

    Session = sessionmaker(bind=engine)
    session = Session()

    # create some groups
    group1 = Group(name="group 1")
    group2 = Group(name="group 2")

    # create some items
    item1 = Item(name="Item 1")
    item2 = Item(name="item 2")
    item3 = Item(name="Item 1")

    # add some items to a group
    group1.items = [item1, item2, item3]
    group2.items = [item2, item3]

    # add all to the session and commit
    session.add_all([group1, group2, item1, item2, item3])
    session.commit()

    # try to delete group 1
    # FAILS when using Postgres!!!
    session.query(Group).filter_by(name="group 1").delete()

    assert session.query(Item).count() == 3
    assert session.query(Group).count() == 1

def run_sqlite():
    run('sqlite://')

def run_postgres():
    with PostgresContainer("postgres:latest") as postgres:
        run(postgres.get_connection_url())

if __name__ == '__main__':
    run_sqlite() # works
    run_postgres() # fails with an error message

sqlite works, but postgres does not. It results in an error:

sqlalchemy.exc.IntegrityError: (psycopg2.errors.ForeignKeyViolation) update or delete on table "group" violates foreign key constraint "item_group_members_group_id_fkey" on table "item_group_members"
DETAIL:  Key (id)=(1) is still referenced from table "item_group_members".```


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source