코드로 우주평화
SQLAlchemy _ ForeignKey 로 연결된 개체 한 번에 삭제하기 본문
SQLAlchemy에서는 cascading 옵션을 활용하여 관계된 개체(Entity)를 한 번에 삭제할 수 있다.
방법 1. 부모 relationship 에서 cascade 매개변수 지정
두 테이블 간의 관계를 정의할 때, 상위 개체와 하위 개체가 함께 삭제되도록 cascade 매개변수를 지정할 수 있다.
from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship('Child', cascade='delete')
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
Parent 클래스가 Child 개체와 관계가 있음을 명시하고 cascade 매개변수를 "delete"로 설정했다. 이렇게 하면 부모 개체가 삭제될 때 관련된 모든 자식 개체도 삭제된다.
Parent 개체와 관련된 모든 Child 개체를 삭제하려면 간단히 session.delete(parent)를 호출하면 된다. ORM은 연결된 모든 Child 개체도 함께 삭제한다.
방법 2. 자식 ForeignKey 에 ondelete 제약 조건 추가
자식 테이블에서 ForeignKey 제약 조건을 정의할 때, ondelete="CASCADE" 옵션을 추가할 수 있다.
from sqlalchemy import Column, Integer, ForeignKey
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey("parent.id", ondelete="CASCADE"))
Child 클래스의 parent_id 필드에 ondelete 매개변수를 추가하고 "CASCADE"로 지정했다. 이 방법은 부모 테이블에 자식과의 관계가 정의되어 있지 않아도 된다.
부모 테이블에 정의되어 있지 않아도 Parent 개체가 삭제될 때 Child 개체들도 함께 삭제 된다.
둘의 차이점
방법1, 방법2 모두 부모 개체가 삭제될 때 관련된 개체도 함께 삭제하지만 둘의 동작 방식에는 차이가 있다.
방법1(relationship - cascade)은 ORM 계층에서 관계를 정의할 때 사용하지만, 방법2(ForeignKey - ondelete)는 데이터베이스 스키마 수준에서 외래 키 제약 조건을 정의할 때 사용한다.
공식문서에서는 방법2가 더 효율적이라고 말한다. ORM 과 달리, 데이터베이스는 여러 관계의 CASCADE 연산을 한 번에 수행할 수 있기 때문이다.
이 둘의 사용법과 차이에 대해 더 자세히 알고 싶다면 아래 공식문서를 참고하자.
참고 문서
'나는 이렇게 학습한다 > DB' 카테고리의 다른 글
Sqlalchemy 의 scalar 메서드들을 살펴보자 (0) | 2024.01.24 |
---|---|
Sqlalchemy 에서 joinedload 할 때, The unique() method must be ... 에러 해결방법 (0) | 2023.08.30 |
데이터베이스에서 인덱스는 왜 사용하는 걸까? (0) | 2022.03.19 |
트랜젝션이란? (0) | 2022.03.18 |
RDB와 NoSQL를 차이 (0) | 2022.03.18 |