이번 주 학습 요약
이번 주에는 Streamlit으로 화면을 구성하는 단계에서 한 걸음 더 나아가, FastAPI 서버와 데이터베이스를 연결한 CRUD 기능을 구현했다.
Streamlit에서 입력받은 데이터를 FastAPI로 전달하고, FastAPI가 데이터베이스와 통신한 뒤 처리 결과를 다시 화면에 보여주는 전체 흐름을 실습했다. 처음에는 각각의 코드가 따로 움직이는 것처럼 느껴졌지만, 상품과 고객 관리 기능을 직접 구현하면서 프론트엔드·백엔드·데이터베이스가 어떻게 연결되는지 조금씩 이해할 수 있었다.
특히 단순히 코드를 따라 입력하는 데서 끝나지 않고, 중복된 ID가 계속 저장되거나 수정할 데이터가 존재하지 않는다고 표시되는 문제를 직접 확인하고 해결했다. 덕분에 CRUD는 화면만 만드는 작업이 아니라 데이터가 이동하는 모든 과정을 함께 점검해야 한다는 것을 배웠다.
주요 학습 내용
1. Streamlit 애플리케이션 구조 이해
Streamlit의 입력 위젯과 화면 구성 요소를 이용해 사용자가 데이터를 입력하고 결과를 확인할 수 있는 페이지를 만들었다.
단일 페이지 실습에서 발전해 여러 기능을 나누어 관리하는 구조도 경험했다. 이 과정에서 st.set_page_config()는 다른 Streamlit 명령보다 먼저 실행해야 한다는 점을 알게 됐다. 코드 중간이나 다른 Streamlit 명령 뒤에 작성하면 다음과 같은 오류가 발생할 수 있다.
streamlit.errors.StreamlitSetPageConfigMustBeFirstCommandError
오류 메시지만 보면 복잡해 보이지만, 원인은 페이지 설정 명령의 위치였다. 이를 통해 라이브러리마다 반드시 지켜야 하는 실행 순서와 규칙이 있다는 것을 배웠다.
2. 데이터를 표와 화면으로 출력하기
파이썬의 리스트와 딕셔너리 형태로 준비한 데이터를 Pandas의 데이터프레임으로 변환해 Streamlit 화면에 출력했다.
st.dataframe(data, use_container_width=True)
데이터프레임을 사용하면 여러 데이터를 행과 열로 정리할 수 있어 전체 목록을 확인하기 편했다. 단순히 st.write()로 출력하는 것보다 실제 관리 페이지에 가까운 화면을 만들 수 있었다.
또한 과목과 점수 등의 샘플 데이터를 활용하면서, 데이터를 화면에 보여주기 전에 어떤 형태로 정리해야 하는지도 연습했다.
3. Streamlit과 FastAPI의 역할 구분
이번 주 실습에서 가장 중요했던 부분은 Streamlit과 FastAPI의 역할을 구분하는 것이었다.
- Streamlit: 사용자가 보는 화면과 입력 기능 담당
- FastAPI: 요청을 받아 데이터를 처리하는 서버 담당
- 데이터베이스: 상품과 고객 정보 저장
- HTTP 요청: Streamlit과 FastAPI 사이에서 데이터 전달
사용자가 Streamlit에서 상품 정보를 입력하면 클라이언트 함수가 FastAPI에 요청을 보낸다. FastAPI의 라우터는 요청을 받아 서비스 함수에 전달하고, 서비스에서는 데이터베이스를 조회하거나 데이터를 추가·수정·삭제한다.
처리된 결과는 다시 FastAPI를 거쳐 Streamlit 화면에 표시된다.
이전에는 한 파일 안에서 입력과 출력을 모두 처리했다면, 이번에는 기능에 따라 파일을 분리했다.
- schema: 주고받을 데이터의 형식 정의
- router: 요청 주소와 HTTP 메서드 관리
- service: 실제 데이터 처리
- client: Streamlit에서 FastAPI로 요청 전송
- Streamlit 페이지: 입력과 결과 출력
파일이 많아져 처음에는 복잡했지만, 각각의 역할을 나누면 오류가 발생한 위치를 찾거나 기능을 수정하기가 쉬워진다는 점을 이해했다.
4. 상품과 고객 CRUD 구현
CRUD는 데이터를 다루는 네 가지 기본 기능을 의미한다.
- Create: 데이터 등록
- Read: 데이터 조회
- Update: 데이터 수정
- Delete: 데이터 삭제
이번 주에는 상품과 고객 데이터를 이용해 CRUD의 전체 과정을 실습했다.
상품 관리 기능에서는 상품 ID, 이름, 가격을 입력받아 저장하고, 전체 상품과 특정 상품을 조회했다. 이후 상품 정보를 수정하거나 삭제하는 기능까지 연결했다.
고객 관리 기능에서도 같은 구조를 적용했다.
customer = {
"name": update_name,
"age": int(update_age),
}
화면에서 입력받은 고객 정보를 딕셔너리로 구성해 수정 요청에 전달했다. 상품과 고객이라는 서로 다른 데이터를 사용했지만 CRUD를 구현하는 기본 구조는 비슷했다.
이를 통해 한 번 CRUD 구조를 이해하면 게시글, 회원, 주문 등 다른 데이터 관리 기능에도 응용할 수 있다는 것을 알게 됐다.
실습 및 문제 해결
중복된 상품 ID가 계속 등록되는 문제
상품을 등록할 때 이미 존재하는 ID를 입력해도 데이터베이스에 계속 저장되는 문제가 발생했다.
처음에는 Streamlit 화면의 입력값이나 버튼 처리 문제라고 생각했지만, 실제로는 프론트엔드뿐만 아니라 FastAPI 서비스와 데이터베이스 조회 과정까지 함께 확인해야 했다.
중복 검사가 정상적으로 작동하려면 새로운 상품을 저장하기 전에 같은 ID를 가진 상품이 존재하는지 먼저 조회해야 한다. 또한 조회 결과와 조건문의 판단이 올바르게 연결돼 있어야 한다.
이번 문제를 통해 입력 화면에서만 값을 검사하는 것으로는 부족하다는 것을 배웠다. 서버에서도 중복 여부를 검사해야 잘못된 요청이나 다른 경로로 들어온 데이터까지 막을 수 있다.
수정할 상품이 존재하지 않는다고 표시되는 문제
데이터베이스에 상품이 있는데도 수정 기능을 실행하면 존재하지 않는 상품이라는 결과가 나오는 문제가 있었다.
이 문제를 해결하기 위해 다음 항목을 하나씩 확인했다.
- Streamlit에서 입력한 상품 ID
- 클라이언트 함수에 전달된 값
- FastAPI 요청 주소
- 라우터의 경로 변수
- 서비스 함수의 조회 조건
- 데이터베이스에서 사용하는 ID의 자료형
- 수정 결과를 판단하는 조건문
특히 화면에서 받은 ID와 데이터베이스의 ID가 서로 다른 자료형으로 처리되면 같은 숫자처럼 보여도 정상적으로 조회되지 않을 수 있다는 점을 알게 됐다.
오류가 발생했을 때 한 파일만 반복해서 수정하는 것이 아니라, 데이터가 이동하는 순서를 따라가며 확인하는 방법을 연습할 수 있었다.
조회·수정·삭제 기능의 연결 점검
고객 조회 코드와 기존 상품 조회 예제를 참고해 상품 전체 조회, 한 건 조회, 수정, 삭제 기능을 완성했다.
기능을 구현한 뒤에는 코드가 실행되는지만 보는 것이 아니라 실제 데이터베이스의 값이 바뀌었는지도 확인했다.
- 등록 후 전체 목록에 데이터가 나타나는가?
- 특정 ID를 조회했을 때 올바른 상품이 표시되는가?
- 수정 후 이름과 가격이 변경되는가?
- 삭제 후 해당 데이터가 목록에서 사라지는가?
- 존재하지 않는 ID를 입력했을 때 적절한 결과가 표시되는가?
이러한 확인 과정을 거치면서 화면에 성공 메시지가 나오는 것과 데이터베이스에서 실제 작업이 완료되는 것은 별도로 검증해야 한다는 점을 배웠다.
KPT 회고
Keep: 계속 유지할 점
이번 주에도 전체 코드를 한 번에 완성하기보다 기능을 작은 단계로 나누어 직접 입력하고 실행했다. 한 단계가 정상적으로 작동하는지 확인한 뒤 다음 기능으로 넘어가니 문제가 생겼을 때 원인을 찾기가 더 쉬웠다.
또한 오류 화면, 실행 결과, 데이터베이스 상태를 함께 비교한 것이 문제 해결에 도움이 됐다. 앞으로도 코드만 확인하지 않고 요청과 응답, 실제 저장 결과까지 함께 점검해야겠다.
Problem: 어려웠던 점
프론트엔드, 클라이언트, 라우터, 서비스, 스키마 파일이 나뉘면서 데이터가 어느 파일을 거쳐 이동하는지 혼동할 때가 있었다.
특히 중복 ID 검사와 수정 기능처럼 여러 계층이 연결된 기능은 한 부분의 자료형이나 반환값만 달라도 예상과 다른 결과가 나왔다. 오류가 난 파일만 보고 바로 수정하려다 보니 근본적인 원인을 찾는 데 시간이 걸리기도 했다.
Try: 다음에 시도할 점
앞으로 CRUD 기능을 구현할 때는 먼저 데이터의 이동 과정을 간단하게 정리한 뒤 코드를 작성해 보고 싶다.
예를 들어 수정 기능이라면 다음 순서로 점검할 수 있다.
- Streamlit에서 ID와 수정할 데이터를 입력한다.
- 클라이언트 함수가 FastAPI로 요청을 보낸다.
- 라우터가 ID와 데이터를 서비스 함수에 전달한다.
- 서비스 함수가 기존 데이터를 조회한다.
- 데이터가 존재하면 수정하고 결과를 반환한다.
- Streamlit에서 응답 결과를 표시한다.
또한 정상적인 값만 테스트하지 않고 중복 ID, 존재하지 않는 ID, 빈 문자열, 잘못된 가격 등 예외 상황도 함께 확인하는 습관을 들여야겠다.
다음 주 계획
다음 주에는 이번 주에 만든 CRUD 구조를 다시 복습하면서 각 파일이 어떤 역할을 담당하는지 스스로 설명해 볼 계획이다.
특히 다음 내용을 집중적으로 복습하고 싶다.
- HTTP의 GET·POST·PUT·DELETE 방식
- 요청 데이터와 응답 데이터의 구조
- 경로 변수와 요청 본문의 차이
- 문자열과 정수 자료형 변환
- 중복 데이터 검사
- 존재하지 않는 데이터의 예외 처리
- Streamlit과 FastAPI 사이의 요청 흐름
- CRUD 기능 테스트 방법
이번 주는 화면을 만드는 단계에서 실제 데이터 관리 기능으로 넘어간 시간이었다. 오류도 여러 번 발생했지만, 그 과정에서 프론트엔드와 백엔드가 어떻게 연결되는지 더 구체적으로 이해할 수 있었다.
아직은 여러 파일을 오가며 코드를 확인해야 하지만, 상품과 고객 CRUD를 직접 완성하면서 기본적인 웹 애플리케이션의 흐름을 경험했다는 점에서 의미 있는 한 주였다.
'AI 오케스트레이션 캠프 > 주간 회고' 카테고리의 다른 글
| [SK네트웍스 Family 엔코아AI캠퍼스] AI 오케스트레이션 캠프 1기_8월 1주차 회고 (0) | 2026.08.07 |
|---|---|
| [SK네트웍스 Family 엔코아AI캠퍼스] AI 오케스트레이션 캠프 1기_7월 4주차 회고 (0) | 2026.07.24 |
| [SK네트웍스 Family 엔코아AI캠퍼스] AI 오케스트레이션 캠프 1기_7월 3주차 회고 (0) | 2026.07.17 |
| [SK네트웍스 Family 엔코아AI캠퍼스] AI 오케스트레이션 캠프 1기_7월 2주차 회고 (0) | 2026.07.12 |
댓글