강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

usna7님의 프로필 이미지
usna7

작성한 질문수

[매일 완독 챌린지] 저자와 함께하는 <FastAPI로 기획에서 출시까지>

8.5절 : 캘린더 예약 가져오기 API 구현하기 (p321~p338)

4주 3회차 과제

해결된 질문

작성

·

8

0

중복 예약을 데이터베이스의 고유값 제약으로 예방하는 방법

조건은

1)동일 일자와 동일 타임 슬롯인 경우 중복으로 간주 2)약속(부킹)이 취소되어 attendance_status 모델 필드값이 cancellled인 경우 예약 가능

 

위를 구현하기 위해 데이터베이스에게 아래 정보가 고유해야 한다는 특별한 규칙을 알려줄 수 있습니다.

1)누가 예약하는지

2)언제 예약하는지

3)어느 시간대에 예약하는지

위의 세가지가 모두 같으면 중복 예약이라고 판단 합니다.

 

취소된 재예약은 가능하게 하기 위해

고유성 규칙에 한가지 예외를 부여합니다.

호스트, 날짜, 시간 슬롯의 조합은 고유해야 한다. 예외적으로 예약상태가 "취소됨"이라면

그 예약은 위의 고유성 규칙을 무시해 달라고 합니다.

 

새로운 예약 생성 시:

  • 데이터베이스는 예약하려는 호스트, 날짜, 시간슬롯 정보를 보고, 현재 '취소됨' 상태가 아닌 다른 예약이 이미 있는지 찾아봅니다.

  • 만약 '취소됨' 상태가 아닌 다른 예약이 이미 같은 자리에 있다면, 데이터베이스는 "안돼! 이미 예약된 자리야!"라고 하며 새로운 예약을 저장하지 못하게 합니다.

  • 만약 같은 자리에 '취소됨' 상태가 아닌 예약이 없다면, 데이터베이스는 새로운 예약을 성공적으로 저장합니다.

예약 취소 시:

  • 어떤 예약이 '취소됨(cancelled)' 상태로 변경되면, 데이터베이스의 이 "특별한 규칙"은 그 취소된 예약을 더 이상 고유성 검사 대상에서 제외합니다.

  • 이제 그 자리는 "비어있는" 것처럼 간주되므로, 다른 사람이 같은 호스트, 날짜, 시간슬롯 정로 새로운 예약을 만들 수 있게 됩니다.

답변 2

0

한날님의 프로필 이미지
한날
지식공유자

기술 요구사항을 잘 기술하셨어요.

이 요구사항을 PostgreSQL로 구현한다면 조건부 고윳값 제약으로 충족할 수 있습니다. 🙂 조건부 고윳값 제약을 지원하지 않는 데이터베이스(예 : SQLite 등)를 사용한다면 애플리케이션 계층에서 검사하거나 다른 방식으로 데이터베이스의 고윳값 제약을 활용할 수 있지요. 예를 들어, 부킹에 이력(revision)을 저장하고, 고윳값 제약은 when, timeslot_id, revision으로 묶어서 설정한 후, 예약 상태인 부킹의 revision은 고정한다면 SQLite에서도 고윳값 제약으로 무결성을 충족할 수 있지요.

0

안녕하세요, 인프런 AI 인턴입니다. usna7님께서 설명하신 과제는 데이터베이스에서 중복 예약을 방지하기 위해 고유성 제약 조건을 설정하고, 특정 조건에 따라 예외를 허용하는 구현이 필요한 내용입니다.

데이터베이스 설계 및 구현

  1. Unique Index 생성하기: 동일 일자와 타임 슬롯의 중복을 피하기 위해 고유한 인덱스를 생성합니다.
   CREATE UNIQUE INDEX uq_booking_slot ON bookings (host_id, booking_date, time_slot_id) WHERE attendance_status <> 'cancelled';
  • 여기서 host_id, booking_date, time_slot_id가 고유한 조합이 되어야 한다고 지정합니다. 그러나 attendance_status가 ‘cancelled’일 경우에는 예외로 처리되도록 합니다.
  1. Python에서의 구현: SQL 모델의 고유성 제약 조건을 정의하여 고유 인덱스를 구현합니다.
   from sqlalchemy import UniqueConstraint, text
   from sqlmodel import SQLModel
   
   class Booking(SQLModel, table=True):
       __tablename__ = "bookings"
       __table_args__ = (
           UniqueConstraint("host_id", "booking_date", "time_slot_id", 
                            name="uq_booking_slot", 
                            postgresql_where=text("attendance_status <> 'cancelled'")),
       )

동작 원리

  • 새로운 예약 생성 시: 데이터베이스는 이미 해당 호스트, 날짜, 시간 슬롯에 ‘취소됨’ 상태가 아닌 예약이 있는지 확인합니다. 없다면 새로운 예약을 허용. 그렇다면 예약이 거부됩니다.

  • 예약 취소 시: 예약 상태가 ‘취소됨’으로 바뀌면, 해당 레코드는 고유성 검사에서 제외되어 다른 예약을 허용합니다.

참고 URL

  • 관련 강의나 여러 토론에서 다뤄진 상황에 대해 더 깊게 이해하고 싶으시면, 인프런 커뮤니티에서 찾아볼 수 있습니다: 관련 질문 보기

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

usna7님의 프로필 이미지
usna7

작성한 질문수

질문하기