장고 on_delete=models.CASCADE
class Booking(TimeStampModel):
...
class Meta:
db_table = 'bookings'
class Passenger(TimeStampModel):
...
booking = models.ForeignKey('Booking', on_delete = models.CASCADE)
class Meta:
db_table = 'passengers'
장고에서 데이터 모델링을 할때 외래키에 cascade속성을 주면
데이터를 삭제하면 해당 데이터를 외래키로 참조하는 데이터들이 같이 삭제가 된다.
In [16]: Booking.objects.all().delete()
Out[16]: (2, {'bookings.Passenger': 1, 'bookings.Booking': 1})
bookings테이블에 데이터1, passengers테이블에 bookings테이블을 참조하고있던 데이터 1이 있던 상황.
bookings의 모든 데이터를 지우니까 cascade옵션으로 해당 데이터를 참조하고있던 passenger도 삭제가 됐다.
그런데 모델링을 이렇게 해도 실제 sql에서 테이블을 만들 때는 이게 적용되지 않는다.
그래서 데이터베이스에서 데이터를 직접 지우면 왜래키 제약조건때문에 데이터가 삭제되지 않고,
제약조건을 해제하고 삭제를 해도 bookings의 데이터만 지워지고 참조하고있는 passengers의 데이터는 지워지지 않는다.
mysql에서 cascade조건을 주는법
CREATE TABLE rooms (
...
FOREIGN KEY (`booking_id`)
REFERENCES bookings (`id`)
ON DELETE CASCADE
);
sql에서 직접 테이블을 생성하면서 이렇게 on delete cascade 속성을 주면 된다.
그런데 장고 모델에서 on_delete=models.CASCADE속성을 주면 테이블을 생성할 때 cascade속성이 생기지 않는다.
sql 테이블이 어떻게 생성되었는지 확인하는법
SHOW CREATE TABLE `passengers`;
위처럼 따옴표 안에 테이블명을 넣으면 테이블이 생성될 때 명령어를 볼 수 있다.
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| passengers | CREATE TABLE `passengers` (
`id` bigint NOT NULL AUTO_INCREMENT,
`created_at` datetime(6) NOT NULL,
`updated_at` datetime(6) NOT NULL,
`first_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`last_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`gender` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`birthday` date NOT NULL,
`booking_id` bigint NOT NULL,
PRIMARY KEY (`id`),
KEY `passengers_booking_id_fcb39247_fk_bookings_id` (`booking_id`),
CONSTRAINT `passengers_booking_id_fcb39247_fk_bookings_id` FOREIGN KEY (`booking_id`) REFERENCES `bookings` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci |
+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
그러면 이렇게 확인을 해볼수 있는데
외래키인 booking_id에 on delete cascade 조건이 없는 것을 확인할 수 있다.
그래서 booking을 삭제하면서 해당 booking을 참조하는 passengers데이터를 함께 삭제하고 싶다면
sql에서 직접 삭제하지 말고 장고의 manage.py를 이용해 쉘에서 삭제하는 것이 좋다.
참고
'Django' 카테고리의 다른 글
| DRF | 페이지네이션 (0) | 2022.08.30 |
|---|---|
| Django | models : verbose_name (0) | 2022.08.20 |
| Django | 프로젝트 초기세팅 (0) | 2022.07.16 |
| Django | 파이썬 쉘에서 db에 있는 데이터 id값 바꾸기 (0) | 2022.07.06 |
| Django | 다대다(many-to-many) 관계 만들기 (0) | 2022.07.05 |