inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

윈도우 build test오류 질문

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 클린도 해보고 다시 시도해보아도 test때문에 실패 한다네요.. 왜이럴까요..??

  • java
  • spring
  • mvc
  • spring-boot
escho94 댓글 2 좋아요 1 조회수 152

4주 3회차 과제

해결됨

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

데이터베이스 고윳값 제약으로 예방하는 구현에 대해서 조사했습니다. 동일 일자와 동일 타임슬롯인 경우 중복 Booking에 unique index를 생성하는 것인데 동일 일자 (when)과 동일 타임슬롯(time_slot_id) 조건을 생성하면 됩니다. CREATE UNIQUE INDEX uq_booking_slot ON bookings (when, time_slot_id); class Booking(SQLModel, table=True): __tablename__ = "bookings" __table_args__ = ( UniqueConstraint("when", "time_slot_id", name="uq_booking_slot"), ) attendance_status 필드값이 cancelled인 경우 PostgreSQL의 경우 partial unique index가 가능합니다. where를 사용해서 field가 cancelled가 아닌 경우에 unique 제약을 걸면 됩니다. CREATE UNIQUE INDEX uq_booking_slot ON bookings (when, time_slot_id) WHERE attendance_status <> 'cancelled' ; class Booking(SQLModel, table=True): __tablename__ = "bookings" __table_args__ = ( UniqueConstraint("when", "time_slot_id", name="uq_booking_slot"), postgresql_where=text("attendance_status <> 'cancelled'") ) 다중 컬럼에 대한 unique는 종종 사용하는 방법이었는데 where를 이용해서 조건을 설정할 수 있는 건 이번에 첨 알았습니다. 필요하면 python에서 처리하곤 했었는데 데이터베이스 기능으로 이용하는게 레이스 컨디션도 피할 수 있고 장점이 있어보이네요. 실무에 적용할때도 꼭 이용해보겠습니다.

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
김도현 댓글 1 좋아요 0 조회수 64

4주 5회차 과제

해결됨

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

파일 삭제 정책 booking을 삭제할때 해당 booking과 업로드된 파일을 같이 삭제하는 정책 의미없는 파일이 남아있는 것은 저장 공간 낭비 유출 위험을 줄여준다(?) (예: 삭제된 booking의 파일을 남겨두어 총 100개의 파일이 저장된 상태라고 가정. 그 중에 70개는 필요한 파일, 나머지 30개는 필요없는(삭제된 booking) 파일임. 파일을 바로 제거하지 않아서 100개가 다 유출되는 것보다 의미없는 파일을 바로바로 제거하여 70개만 유출되는 것이 더(?) 낫다..) 그러나 한편으로는 트래픽이 적은 시간에 삭제된 booking의 파일을 주기적으로 정리하는 로직을 실행하는 것이 더 나을까 하는 생각도 드네요

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
ayo 댓글 2 좋아요 0 조회수 56

4주 1회차 과제

해결됨

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

is_host / 캘린더 보유 여부 중에 어느 것을 사용할까? 둘 다? is_host 는 반드시 사용할 것 같음 is_host 필드가 있으면 캘린더 라는 다른 엔티티에 의존하지 않고 is_host 만으로 호스트 여부를 판단할 수 있어서 캘린더 보유 여부는 선택적일 것 같음 아래와 같은 정책을 설정해야할 필요가 있을때 is_host 인데 캘린더가 있는 경우 s_host 인데 캘린더가 없는 경우 아니면 '호스트는 최소 하나 이상의 캘린더는 있어야 한다' 같은 정책

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
ayo 댓글 2 좋아요 0 조회수 49

4주 1회차 과제

해결됨

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

기획의 관점에서 Host 체크 방법 is_host 필드 체크 사용자가 호스트인지 먼저 확인을 하게 되므로 호스트 등록, 호스트만 조회, 호스트에 주어진 권한 제어 등 호스트를 따로 관리하고 싶을때 장점이 있습니다 캘린더 보유 체크 캘린더로 호스트일 경우는 호스트, 게스트 구분이 회원 등급이나 종류가 아닌 모두가 호스트나 게스트가 될수 있고 예약이 서로에게 일어날 수 있을때 장점이 있습니다. 구글 캘린더로 예를 들면 모두가 초대가 가능하고 초대도 가능한 방식입니다. 내가 선택한다면 저라면 기본적으로는 is_host 필드로 체크하고 실제 예약을 받는다면 캘린더 체크를 이후에 하겠습니다. 호스트 관리를 따로 하게 되면 호스트만 따로 조회도 가능하고 호스트를 하고 싶지 않을때는 호스트가 되지 않는 것도 가능합니다. 또한 is_host를 기본 true로 하게 되면 모두가 호스트가 되는 방식도 가능하므로 앞에서 가정한 모두가 호스트/게스트인 방식도 쉽게 전환이 가능합니다. 예약 가능한 캘린더 체크는 실제로 이사람이 호스트라고 하더라도 예약일자가 있는지에 따라 예약화면 컨트롤 등이 가능하기 때문에 체크가 필요합니다. 요약하면 is_host 체크를 할 때 상황에 따라 유연하게 호스트 <-> 게스트 전환이 쉽고 필요한 경우 호스트이면서 게스트인 정책도 가능하기 때문에 좀 더 유연한 방법이라고 생각합니다.

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
김도현 댓글 2 좋아요 0 조회수 45

part5. 청팀홍팀 풀이 질문 드립니다.

미해결

2026 코딩테스트 올인원 [JAVA]

안녕하세요! 남노씨님 덕분에 강의 잘 들으며 학습중입니다. part5.청팀홍팀 풀이로 보여주신 것에서 질문이 있습니다. 문제의 Input 예시 이해가 잘 되지 않았습니다. 제가 혼자 생각했을 때는, 주어진 friends[][] 배열을 인접리스트로 만들어야한다고 생각했고, 서로는 쌍방이니 양방향 그래프. 양방향 값을 인접리스트에 넣어주어야 한다고 생각했습니다. 근데 input 예시를 보니, 예시1은 서로 양방향 없이 구성되어있고, 예시2는 인접리스트처럼 서로 양방향으로 구성되어있습니다. 이상황에서 인접리스트를 구성하려니 예시2로는 중복이 발생하더라구요. 1. 예시 1,2 기준이 달라보이는데 어떻게 해석해야 좋을까요? 2. 양방향 그래프=무방향 그래프 같다고 볼 수 있나요? 이 문제의 경우 어떤 그래프인지, 구현의 차이점이 있는지 궁금합니다. 3. 풀이에서는 인접리스트를 별도로 안만들고, 받은 배열 자체를 인접리스트인것처럼 바로 사용하였는데, 이전 풀이와 비교해서 왜 이렇게 사용하였는지 궁금합니다. (문제에서 캐치할 수 있는 차이점이 뭘지) 4. dfs/bfs에서 사용하는 자료구조(큐,재귀/스택)는 풀이에 사용하지 않으셨는데 문제 상 필요 없는건지, 이분그래프일 때 사용 안해도 되는지 궁금합니다. (일단 bfs 큐 사용한 구조 만들고 시작했는데 이렇게 접근하면 안되는걸까요?ㅠㅠ) 이해 도와주시면 감사하겠습니다 :)

  • java
  • 코딩-테스트
  • 알고리즘
  • data-structure
송유진 댓글 3 좋아요 0 조회수 122

4주 4회차 과제 제출

미해결

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

쟁점 정리 예약 일정 변경과 관련해서 결정해야 할 핵심은 다음과 같습니다: 일자/타임슬롯 변경을 허용할 것인가? vs 취소 후 재예약만 가능하게 할 것인가? 변경을 허용한다면, 언제까지 허용할 것인가? 당일 변경은 불가능하다 (이건 확정) 내가 선택한 정책 일자/타임슬롯 변경을 허용하되, 예약일 24시간 전까지만 가능 근거: "취소 → 재예약" 방식은 사용자가 불편하고, 원하는 시간이 이미 찼을 수도 있음 24시간 전까지는 게스트에게 충분한 유연성을 주면서도, 호스트가 하루 전부터 안정적으로 준비할 수 있음 규칙이 단순해서 사용자가 이해하기 쉽고, 구현도 간단함 구현 시나리오 시나리오 1: 여유 있는 변경 (성공) 민수는 2월 10일 오후 2시를 예약했습니다. 2월 7일에 2월 11일 오후 4시로 바꾸고 싶어졌습니다. → 변경 가능 (24시간 이상 여유) → "변경이 완료되었습니다." 시나리오 2: 임박한 변경 시도 (실패) 지영은 2월 10일 오후 2시를 예약했습니다. 2월 9일 오후 3시에 시간을 바꾸려고 합니다. → 변경 불가 (24시간 미만) → "예약일 24시간 전까지만 변경 가능합니다. 취소 후 재예약해주세요." 시나리오 3: 당일 변경 시도 (실패) 현우는 2월 10일 오후 2시를 예약했습니다. 2월 10일 오전 11시에 오후 4시로 바꾸려고 합니다. → 변경 불가 (당일) → "당일 일정 변경은 불가능합니다." 이상입니다.

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
고리오영감 댓글 2 좋아요 0 조회수 59

4주 1회차 과제 제출합니다.

해결됨

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

저는 is_host 필드와 calendar 존재 여부를 둘 다 검증해야 한다 고 판단했습니다. 왜 두 가지를 모두 사용해야 할까요? 우선 두 요소는 서로 다른 의미 를 가지고 있다고 생각합니다. is_host : 이 사용자가 호스트 자격 이 있는가? (역할) calendar 존재 : 이 호스트가 실제로 운영 중 인가? (상태) 현실로 비유하자면, is_host는 사업자등록증을 가지고 있는 상태이고, calendar가 있다는 건 실제로 가게를 오픈한 상태라고 볼 수 있습니다. 사업자등록증은 있지만 아직 가게를 열지 않은 사람도 있을 수 있잖아요? 그래서 둘 중 하나만 체크하면 문제가 생긴다고 봅니다. 만약 calendar 존재 여부만 체크한다면? calendar만 보고 판단하면 권한 체계가 무너질 수 있습니다. 예를 들어 일반 사용자가 억지로 캘린더를 생성하면 호스트로 둔갑할 수 있는 보안 문제가 생기죠. 또 호스트가 일시적으로 캘린더를 삭제했다가 다시 만들 때마다 권한 관리가 복잡해집니다. 만약 is_host만 체크한다면? 반대로 is_host만 체크하면, 캘린더가 없는데도 예약 관련 API를 호출할 수 있게 되어서 500 에러가 발생할 수 있습니다. "호스트인데 캘린더는 없는" 이상한 상태를 어떻게 처리해야 할지도 애매해지고요. 두 가지를 순차적으로 검증하는 게 좋습니다 저는 이렇게 단계적으로 확인하는 게 맞다고 봅니다: 먼저 is_host로 호스트 자격이 있는지 확인 그 다음 calendar 존재로 실제 운영 가능한지 확인 이렇게 하면 사용자에게도 명확한 피드백을 줄 수 있어요. "호스트 권한이 없습니다" vs "캘린더를 먼저 생성해주세요" 처럼 무엇을 해야 하는지 정확히 알려줄 수 있죠. 미래 확장성도 고려했습니다 나중에 서비스가 커지면 호스트 상태를 더 세분화할 수도 있을 것 같아요: 준비 중 호스트 (is_host=true, 캘린더 없음) → 대시보드 접근만 가능 운영 중 호스트 (is_host=true, 캘린더 있음) → 모든 기능 사용 가능 휴면 호스트 (is_host=true, 캘린더 비활성화) → 기존 예약 조회만 가능 이런 식으로 관리하려면 역할과 리소스를 분리해서 체크하는 게 필수라고 생각합니다. 성능 걱정은 없을까요? is_host는 User 모델의 필드라서 추가 DB 쿼리가 필요 없고, calendar 조회도 어차피 해야 하는 작업이라 성능에 큰 영향은 없다고 봅니다.

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
고리오영감 댓글 1 좋아요 0 조회수 56

테스트 관련 공부에 대한 조언을 얻고 싶습니다

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 아니오 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 솔직히 강의에 관련된 질문과는 거리가 먼 내용이어서 질문을 해야 하나 말아야 하나 고민하다가 결국 질문하는 게 좋겠다고 생각되어 질문을 올립니다. 강의 중에 강사님께서 중간중간에 test관련 공부를 열심히 해야한다고 하셨는데 혹시 어떤 식으로 공부해야 하는지 그리고 강사님께서는 어떻게 하셨는지, 또 추천하시는 서적이 있다면 그 서적의 제목이 어떻게 되는지 알고 싶습니다.

  • java
  • spring
  • mvc
  • spring-boot
야지노 댓글 2 좋아요 0 조회수 142

path 쿼리 관련 질문드립니다!

해결됨

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

학습 관련 질문을 최대한 상세히 남겨주세요! 고민 과정도 같이 나열해주셔도 좋습니다. 먼저 유사한 질문이 있었는지 검색해보세요. 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요! 20:15 경 작성해주신 findByPath 의 함수에서 article_id 의 경우 함께 조회할 필요가 없나요? 이전에 생성했던 unique index 구조를 생각해보면 article_id 와 path 2개로 복합 인덱스를 생성하였기 때문에 게시글마다 path 에 대한 unique 함을 보장하는 것이기 때문에 조회 시에 findByArticleIdAndPath 과 같은 식으로 해야 할 것 같은데, 제가 잘못 이해한 부분이 있는지 궁금합니다!

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
댓글 2 좋아요 0 조회수 87

4주 2회차 과제

해결됨

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

안녕하세요. 과제를 잘 못 이해한건가 싶기도 하지만 아래와 같은 조건하에 구현을 해 봤습니다. 수업 과정에서 Front-end는 고정인 상황이기 때문에 기존 API는 변경이 없다는 가정하에 변경 해 봤습니다. 시간대1개와 요일n개의 설정이 하나의 row로 묶여있는 상태로는 요일별 시간대 변동에 대응하기 까다로운 것 같아 요일별 개별 row로 저장하도록 일부 수정 하였습니다. API endpoint 모델 변경을 피하기 위해서 내부적으로 여러개의 요일별 row로 나누어 저장하도록 했습니다. 고민중에 작가님께서 올려 놓으신 레퍼런스 코드를 봤는데, 책에서 언급하신 것 처럼 postgres 경우와 sqlite 경우로 코드가 분기 되는 것을 보았고, 지금은 교육 과정이기 때문이라고 생각 하지만 배포 코드와 개발 환경 코드가 다른것은 여러모로 좋지 않은 것 같아 현재는 sqlite 기준으로 개별 DB구현에서만 지원하는 것은 배제하는 방향으로 구현 했습니다. 1과 같이 변경 함으로써, 기 등록된 정보의 수정에서는 개별 날짜 별 시간대 설정 면에서 자유도가 생겼다고 생각 됩니다. 타임슬롯의 변경과 삭제에 관해서는 내부적으로는 time-slot으로 관리하지만, 외부공개 id는 아니므로, 키 로서 start-time, end-time, weekday (API형태로서는 리스트)조합으로 정의 해서 동작 하도록 구현했습니다. 특히 삭제의 경우는 부득이 delete method의 경우는 payload가 포함되는것이 받아들여지지 않는 경우도 있는것을 고려해서, 새 등록 값 두가지(new_start_time과, new_end_time) 값이 모두 제공되고 같은 경우를 특정하여 삭제 동작으로 정의하여 동작하도록 구현했습니다. class TimeSlotUpdateByGroupIn(SQLModel): start_time: time end_time: time weekdays: Weekdays new_start_time: time | None = None new_end_time: time | None = None new_weekdays: Weekdays | None = None @model_validator(mode="after") def check_update_fields(self): update_fields = { "new_start_time": self.new_start_time, "new_end_time": self.new_end_time, "new_weekdays": self.new_weekdays, } if not any(value is not None for value in update_fields.values()): raise ValueError("최소 하나의 수정 필드는 반드시 제공되어야 합니다.") return self @router.post("/time-slots", status_code=status.HTTP_201_CREATED, response_model=TimeSlotOut) async def create_time_slot( user: CurrentUserDep, session: DbSessionDep, payload: TimeSlotCreateIn, ) -> TimeSlotOut: if not user.is_host: raise GuestPermissionError() weekdays = sorted(set(payload.weekdays)) # dup. check with already exist one stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.weekday.in_(weekdays), TimeSlot.start_time < payload.end_time, TimeSlot.end_time > payload.start_time, ) ) result = await session.execute(stmt) existing_time_slot = result.scalars().first() if existing_time_slot: raise TimeSlotOverlapError() time_slots = [ TimeSlot( calendar_id=user.calendar.id, start_time=payload.start_time, end_time=payload.end_time, weekday=weekday, ) for weekday in weekdays ] session.add_all(time_slots) await session.commit() if not time_slots: raise TimeSlotOverlapError() return TimeSlotOut( start_time=time_slots[0].start_time, end_time=time_slots[0].end_time, weekdays=weekdays, created_at=time_slots[0].created_at, updated_at=time_slots[0].updated_at, ) @router.get( "/time-slots/{host_username}", status_code=status.HTTP_200_OK, response_model=list[TimeSlotOut], ) async def get_host_timeslots( host_username: str, session: DbSessionDep, ) -> list[TimeSlotOut]: stmt = ( select(User) .where(User.username == host_username) .where(User.is_host.is_(true())) ) result = await session.execute(stmt) host = result.scalar_one_or_none() if host is None or host.calendar is None: raise HostNotFoundError() stmt = select(TimeSlot).where(TimeSlot.calendar_id == host.calendar.id) result = await session.execute(stmt) time_slots = result.scalars().all() grouped: dict[tuple[time, time], TimeSlotOut] = {} for time_slot in time_slots: key = (time_slot.start_time, time_slot.end_time) if key not in grouped: grouped[key] = TimeSlotOut( start_time=time_slot.start_time, end_time=time_slot.end_time, weekdays=[time_slot.weekday], created_at=time_slot.created_at, updated_at=time_slot.updated_at, ) continue grouped[key].weekdays.append(time_slot.weekday) if time_slot.created_at < grouped[key].created_at: grouped[key].created_at = time_slot.created_at if time_slot.updated_at > grouped[key].updated_at: grouped[key].updated_at = time_slot.updated_at if not grouped: raise TimeSlotNotFoundError() for time_slot in grouped.values(): time_slot.weekdays = sorted(set(time_slot.weekdays)) return list(grouped.values()) @router.patch( "/time-slots", status_code=status.HTTP_200_OK, response_model=TimeSlotOut | None, ) async def update_time_slot( user: CurrentUserDep, session: DbSessionDep, payload: TimeSlotUpdateByGroupIn, ) -> TimeSlotOut | None: if not user.is_host: raise GuestPermissionError() current_weekdays = sorted(set(payload.weekdays)) stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.start_time == payload.start_time, TimeSlot.end_time == payload.end_time, ) ) result = await session.execute(stmt) current_slots = result.scalars().all() if not current_slots: raise TimeSlotNotFoundError() existing_weekdays = sorted({slot.weekday for slot in current_slots}) if existing_weekdays != current_weekdays: raise TimeSlotNotFoundError() delete_only = ( payload.new_start_time is not None and payload.new_end_time is not None and payload.new_start_time == payload.new_end_time ) if delete_only: current_ids = [slot.id for slot in current_slots] await session.execute(delete(TimeSlot).where(TimeSlot.id.in_(current_ids))) await session.commit() return None new_start_time = payload.new_start_time or payload.start_time new_end_time = payload.new_end_time or payload.end_time new_weekdays = sorted(set(payload.new_weekdays or payload.weekdays)) if new_start_time >= new_end_time: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="시작 시간은 종료 시간보다 빨라야 합니다.", ) current_ids = [slot.id for slot in current_slots] stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.weekday.in_(new_weekdays), TimeSlot.start_time < new_end_time, TimeSlot.end_time > new_start_time, TimeSlot.id.not_in(current_ids), ) ) result = await session.execute(stmt) existing_time_slot = result.scalars().first() if existing_time_slot: raise TimeSlotOverlapError() await session.execute(delete(TimeSlot).where(TimeSlot.id.in_(current_ids))) new_time_slots = [ TimeSlot( calendar_id=user.calendar.id, start_time=new_start_time, end_time=new_end_time, weekday=weekday, ) for weekday in new_weekdays ] session.add_all(new_time_slots) await session.commit() return TimeSlotOut( start_time=new_start_time, end_time=new_end_time, weekdays=new_weekdays, created_at=new_time_slots[0].created_at, updated_at=new_time_slots[0].updated_at, )

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
Green Lee 댓글 1 좋아요 0 조회수 65

antigravity 에디터를 쓰신다면 종료해주세요

해결됨

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

해당 에디터 사용시, 크롬 브라우저 원격 지원을 위해 9092포트를 점유하고 있어 kafka가 사용하는 9092포트와 충돌이 발생합니다. 만약 이용중인라면 다른 IDE를 사용하시는게 좋을것 같습니다.

  • java
  • mysql
  • spring-boot
  • kafka
  • redis
Troy 댓글 0 좋아요 1 조회수 141

스크립트 논리곱 설명이 틀린것 같네요

해결됨

기초 탄탄! 독하게 시작하는 Java - Part 1 : 절차적 프로그래밍

코드 설명하실때는 옳게 설명하셨는데 스크립트랑 내용이 다릅니다.

  • java
kekim 댓글 2 좋아요 0 조회수 78

patch 요청시 payload가 넘어가지 않습니다.

해결됨

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

아래 두 요청 코드에서 patch 요청 시 payload가 엔드포인트 함수에서 None으로 잡혀 model_dump()에서 오류가 발생합니다. 원인을 잘 모르겠습니다. [오류] [요청 코드] @pytest.mark.parametrize("payload", [ {"display_name": "푸딩캠프"}, {"email": "hannal@example.com"}, {"display_name": "푸딩캠프", "email": "hannal@example.com"}, ]) async def test_사용자가_변경하는_항목만_변경되고_나머지는_기존_값을_유지한다( client_with_auth: TestClient, # 인증을 받은 클라이언트 payload: dict, # 클라이언트 요청 페이로드 host_user: User, # 클라이언트 사용자 ): # 현재 사용자 정보를 보관한다. before_data = host_user.model_dump() response = client_with_auth.patch("/account/@me", json=payload) # (...) async def test_비밀번호_변경_시_해싱_처리한_비밀번호가_저장되어야_한다( client_with_auth: TestClient, host_user: User, db_session: AsyncSession, ): before_data = host_user.hashed_password payload = { "password": "new_password", "password_again": "new_password", } response = client_with_auth.patch("/account/@me", json=payload) # (...) [엔드포인트] @router.patch("/@me", response_model=UserDetailOut) async def update_user( user: CurrentUserDep, session: DbSessionDep, payload: UpdateUserPayload = Body(...), ) -> User: updated_data = payload.model_dump(exclude_none=True, exclude={"password", "password_again"}) stmt = update(User).where(User.id == user.id).values(**updated_data) await session.execute(stmt) await session.commit() await session.refresh(user) return user [스키마] class UpdateUserPayload(SQLModel): display_name: str | None = Field(default=None, min_length=4, max_length=40) email: EmailStr | None = Field(default=None, max_length=128) password: str | None = Field(default=None, min_length=8, max_length=128) password_again: str | None = Field(default=None, min_length=8, max_length=128) @model_validator(mode="after") def check_all_fields_are_none(self) -> Self: if not self.model_dump(exclude_none=True): raise ValueError("최소 하나의 필드는 반드시 제공되어야 합니다.") return self @model_validator(mode="after") def verify_password(self) -> Self: if self.password is not None or self.password_again is not None: # 둘 중 하나라도 들어오면 둘 다 있어야 함 if not self.password or not self.password_again: raise ValueError("비밀번호 변경 시 password와 password_again을 모두 제공해야 합니다.") if self.password != self.password_again: raise ValueError("비밀번호가 일치하지 않습니다.") @computed_field @property def hashed_password(self) -> str | None: if self.password: return hash_password(self.password) return None [픽스처] @pytest.fixture(autouse=True) async def db_session(): dsn = "sqlite+aiosqlite:///:memory:" engine = create_async_engine(dsn) async with engine.begin() as conn: await conn.run_sync(SQLModel.metadata.drop_all) await conn.run_sync(SQLModel.metadata.create_all) session_factory = create_session(engine) async with session_factory() as session: yield session await conn.run_sync(SQLModel.metadata.drop_all) await engine.dispose() @pytest.fixture() def fastapi_app(db_session: AsyncSession): app = FastAPI() include_routers(app) async def override_use_session(): yield db_session app.dependency_overrides[use_session] = override_use_session return app @pytest.fixture() async def host_user(db_session: AsyncSession): user = account_models.User( username="puddingcamp", hashed_password=hash_password("testtest"), email="puddingcamp@example.com", display_name="푸딩캠프", is_host=True, ) db_session.add(user) await db_session.flush() await db_session.commit() return user @pytest.fixture() def client_with_auth(fastapi_app: FastAPI, host_user: account_models.User): payload = LoginPayload.model_validate({ "username": host_user.username, "password": "testtest", }) with TestClient(fastapi_app) as client: response = client.post("/account/login", json=payload.model_dump()) assert response.status_code == status.HTTP_200_OK auth_token = response.cookies.get("auth_token") assert auth_token is not None client.cookies.set("auth_token", auth_token) yield client

  • python
  • aws
  • tdd
  • FastAPI
  • 북-챌린지
kyo lee 댓글 3 좋아요 0 조회수 79

인텔리제이 무료버젼이 통합되었다는데 30일 무료버전이면 어떻게 사용하나요

미해결

김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음

1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요?예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 질문 제목 그 자체이긴합니다 인텔리제이 무료버전이 없어지고 통합되엇는데 https://www.jetbrains.com/ko-kr/idea/download/?section=windows 해당 사이트에 나와있는걸 다운로드 하면될까요

  • java
  • 객체지향
유준상 댓글 3 좋아요 1 조회수 994

추후 학습 계획 질문

미해결

2026 코딩테스트 올인원 [JAVA]

안녕하세요! 강의 수강 완료 후에는 복습하면서 다양한 문제를 풀어보면서 학습하는 방법이 좋을까요?..

  • java
  • 코딩-테스트
  • 알고리즘
  • data-structure
슝스스 댓글 1 좋아요 0 조회수 101

자바를 처음 배울 때 이런 고민이 드는 게 정상일까요?

해결됨

나도코딩의 자바 기본편 - 풀코스 (20시간)

강의를 볼 때는 이해가 되는데, 막상 퀴즈를 풀려고 하면 어떻게 접근해야 할지 머릿속에서 잘 떠오르지 않습니다. 코드를 작성하는 데도 시간이 오래 걸리고, 결과를 보면 제가 짠 코드가 스스로 보기에 만족스럽지 않을 때가 많습니다. 자바를 처음 배울 때 이런 고민이 드는 것이 당연한 걸까요?

  • java
  • 객체지향
champ 댓글 2 좋아요 1 조회수 195

static이 뭐였는지 기억이 안나요 ㅜㅜ

미해결

나도코딩의 자바 기본편 - 풀코스 (20시간)

static이 뭐였는지 기억이 안나요 ㅜㅜ강의에서 어떤경우에 쓰는지 말씀해주셨던거 같은데 어디인지 기억이 안나요 ㅠㅠ

  • java
  • 객체지향
kmch0802 댓글 2 좋아요 0 조회수 158

섹션 9 실전 질문

미해결

스프링 부트와 리액트로 구현하는 보안 JWT 로그인

강사님 세션 9에서 Secretes Manager나 Parameter Store 를 현업에서도 깃허브 액션 하고 같이 쓰나요? 이거 궁금해서 질문드립니다.

  • react
  • java
  • aws
  • spring-boot
  • spring-security
KMC 댓글 1 좋아요 0 조회수 99

boot 4.x >>> trasasction rolled back log & p6spy(영한님, 수업 자료 업데이트 해주시면 감사하겠습니다!!)

해결됨

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 일단 현재 yml 강의 자료 기준으로는 trasaction rolled back에 대한 로그가 찍히질 않는데, 해당 옵션을 추가해봤습니다. org.springframework.orm.jpa: trace #JPA 트랜잭션 관련 로그 그랬더니 찍히긴 하던데 약간 이상하게? 찍힙니다. 2026-01-07T02:05:57.767+09:00 DEBUG 5469 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Initiating transaction rollback 2026-01-07T02:05:57.767+09:00 DEBUG 5469 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Rolling back JPA transaction on EntityManager [SessionImpl(1610625797<open>)] 혹시나 다른 옵션이 있을까? class가 아니라 SessionImpl? 이렇게 나오네요. 이건 제가 공식 문서를 봐봤는데, 다른분들께 도움이 될까 싶어서요, 나중에 자료도 업데이트 해주시면 좋을 것 같아요! https://github.com/gavlyukovskiy/spring-boot-data-source-decorator?tab=readme-ov-file#quick-start 현재 저는 부트 4 버전을 사용중인데, 4버전 부터는 p6spy를 1.10.0 이 아닌 2.0.0으로 해줘야 합니다! implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:2.0.0' 현재 자료 기준은 1.10.0이라 수정해 주시면 좋을 것 같습니다! (그리고 3버전도 1.12.1 로 올라갔습니다!) 사실 2번은 질문이라기 보다는 알려드리고 싶은 부분이었고, 1번만 트랜잭션 로그를 다르게 찍는 방법? 이 있는지 궁금합니다.

  • java
  • spring
  • 웹앱
  • spring-boot
  • jpa
Minho Lee 댓글 2 좋아요 1 조회수 234

인기 태그

인프런 TOP Writers

주간 인기글