如何使用ForeignKeyConstraint和复合外键与SQLAlchemy级联删除?

2024-04-23 11:36:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正忙于在一组表上设置SQLalchemy级联删除,其中一个表作为双复合主键引用为外键。下面是一些需要理解的代码示例:

from sqlalchemy import Column, Integer, ForeignKey, ForeignKeyConstraint
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declared_attr



Base = declarative_base()

class Dad(Base):
    __tablename__ = "dad"
    id = Column(Integer, primary_key=True)
    children = relationship("Child", back_populates="dad", passive_deletes=True)

class Mom(Base):
    __tablename__ = "mom"
    id = Column(Integer, primary_key=True)
    children = relationship("Child", back_populates="mom", passive_deletes=True)

class Child(Base):
    __tablename__ = "child"
    dad_id = Column(Integer, ForeignKey("dad.id", ondelete="CASCADE"), primary_key=True)
    mom_id = Column(Integer, ForeignKey("mom.id", ondelete="CASCADE"), primary_key=True)

    dad = relationship("Dad", back_populates="children")
    mom = relationship("Mom", back_populates="children")
    toys = relationship("Toy", back_populates="child", passive_deletes=True)

class Toy(Base):
    __tablename__ = "toy"
    id = Column(Integer, primary_key=True)
    dad_id = Column(Integer, nullable=False)
    mom_id = Column(Integer, nullable=False)
    child = relationship("Child", back_populates="toys")

    @declared_attr
    def __table_args__(cls):
        return (
            ForeignKeyConstraint(
                ["dad_id", "mom_id"],
                ["child.dad_id", "child.mom_id"],
                ondelete="CASCADE", onupdate="CASCADE"
            ),
        )

我的问题是,当我实例化爸爸、妈妈、孩子和一些玩具时,我无法级联删除孩子(例如)。我得到以下错误:

sqlalchemy.exc.IntegrityError: (psycopg2.errors.ForeignKeyViolation) update or delete on table "child" violates foreign key constraint "toy_dad_id_mom_id_fkey" on table "toy"

DETAIL: Key (dad_id, mom_id)=(1, 1) is still referenced from table "toy".