feat: error-storage 저장소 초기 설정 및 get_materials API 수정사항 추가
🎯 저장소 목적: 개발 중 발생한 오류와 해결방법 기록 동일 오류 재발 방지 및 학습 자료 📁 첫 번째 사례: get_materials API JSON 직렬화 오류 해결 PostgreSQL Row 객체 → 딕셔너리 변환 방법 상세한 문제 분석 및 해결 과정 문서화 ✅ 완료: TK-MP-Project 백엔드 API 수정 성공
This commit is contained in:
37
README.md
Normal file
37
README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
Error Storage Repository
|
||||
📋 개요
|
||||
개발 중 발생한 오류들과 해결 방법을 저장하는 저장소입니다.
|
||||
📁 구조
|
||||
error-storage/
|
||||
├── api-fixes/ # API 관련 오류 수정
|
||||
│ └── get-materials-fix/ # get_materials API 수정
|
||||
├── database-fixes/ # 데이터베이스 관련 수정
|
||||
├── frontend-fixes/ # 프론트엔드 관련 수정
|
||||
└── deployment-fixes/ # 배포 관련 수정
|
||||
🎯 목적
|
||||
|
||||
동일한 오류 재발 방지
|
||||
해결 과정 학습 자료
|
||||
팀원들과 지식 공유
|
||||
디버깅 시간 단축
|
||||
|
||||
📚 카테고리별 오류 모음
|
||||
API 관련 오류
|
||||
|
||||
get_materials API JSON 직렬화 오류
|
||||
|
||||
향후 추가 예정
|
||||
|
||||
Database 연결 오류
|
||||
Frontend 렌더링 오류
|
||||
Docker 배포 오류
|
||||
네트워크 설정 오류
|
||||
|
||||
🔧 사용 방법
|
||||
|
||||
오류 발생 시 해당 카테고리 폴더에 기록
|
||||
문제 상황, 원인 분석, 해결 방법 상세 기록
|
||||
재현 가능한 코드와 테스트 방법 포함
|
||||
|
||||
📅 마지막 업데이트
|
||||
2024-07-15
|
||||
55
api-fixes/get-materials-fix/README.md
Normal file
55
api-fixes/get-materials-fix/README.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# get_materials API 응답 오류 수정
|
||||
|
||||
## 🚨 문제 상황
|
||||
- **오류**: TypeError - Object of type 'RealDictRow' is not JSON serializable
|
||||
- **원인**: PostgreSQL Row 객체를 바로 JSON으로 변환 시도
|
||||
- **위치**: `/api/materials` 엔드포인트
|
||||
|
||||
## 🔍 문제 원인 분석
|
||||
|
||||
### Before (오류 발생)
|
||||
```python
|
||||
materials = []
|
||||
for row in cur.fetchall():
|
||||
materials.append(row) # ← psycopg2.extras.RealDictRow 객체
|
||||
|
||||
return jsonify({
|
||||
'data': materials # ← JSON 직렬화 불가능!
|
||||
})
|
||||
왜 오류가 발생했나?
|
||||
|
||||
psycopg2.cursor.fetchall() → RealDictRow 객체 반환
|
||||
Flask.jsonify() → Python dict만 JSON 변환 가능
|
||||
RealDictRow ≠ dict → TypeError 발생
|
||||
|
||||
✅ 해결 방법
|
||||
After (정상 작동)
|
||||
pythonmaterials = []
|
||||
for row in cur.fetchall():
|
||||
# 명시적으로 딕셔너리 변환
|
||||
material = {
|
||||
'id': row[0],
|
||||
'job_number': row[1],
|
||||
'item_number': row[2],
|
||||
'description': row[3],
|
||||
'category': row[4],
|
||||
'quantity': row[5],
|
||||
'unit': row[6],
|
||||
'created_at': row[7].isoformat() if row[7] else None
|
||||
}
|
||||
materials.append(material)
|
||||
|
||||
return jsonify({'data': materials})
|
||||
🔧 핵심 수정사항
|
||||
|
||||
인덱스 접근: row[0], row[1], ... 방식으로 값 추출
|
||||
명시적 변환: 각 필드를 수동으로 딕셔너리에 매핑
|
||||
날짜 처리: datetime → isoformat() 변환 추가
|
||||
|
||||
📅 수정 정보
|
||||
|
||||
날짜: 2024-07-15
|
||||
프로젝트: TK-MP-Project
|
||||
파일: backend/app.py
|
||||
함수: get_materials()
|
||||
결과: API 응답 정상화 완료
|
||||
61
api-fixes/get-materials-fix/fixed_api.py
Normal file
61
api-fixes/get-materials-fix/fixed_api.py
Normal file
@@ -0,0 +1,61 @@
|
||||
"""
|
||||
get_materials API 응답 오류 수정
|
||||
문제: PostgreSQL Row 객체 JSON 직렬화 불가능
|
||||
해결: 명시적 딕셔너리 변환
|
||||
|
||||
날짜: 2024-07-15
|
||||
프로젝트: TK-MP-Project
|
||||
"""
|
||||
|
||||
@app.route('/api/materials', methods=['GET'])
|
||||
def get_materials():
|
||||
"""수정된 자재 목록 조회 API - Row 객체 직렬화 문제 해결"""
|
||||
try:
|
||||
job_number = request.args.get('job_number')
|
||||
|
||||
if not job_number:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': 'job_number parameter is required'
|
||||
}), 400
|
||||
|
||||
with get_db_connection() as conn:
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute("""
|
||||
SELECT
|
||||
m.id, m.job_number, m.item_number, m.description,
|
||||
m.category, m.quantity, m.unit, m.created_at
|
||||
FROM materials m
|
||||
WHERE m.job_number = %s
|
||||
ORDER BY m.item_number
|
||||
""", (job_number,))
|
||||
|
||||
# 🔧 핵심 수정: Row 객체를 명시적으로 딕셔너리로 변환
|
||||
materials = []
|
||||
for row in cur.fetchall():
|
||||
material = {
|
||||
'id': row[0],
|
||||
'job_number': row[1],
|
||||
'item_number': row[2],
|
||||
'description': row[3],
|
||||
'category': row[4],
|
||||
'quantity': row[5],
|
||||
'unit': row[6],
|
||||
'created_at': row[7].isoformat() if row[7] else None
|
||||
}
|
||||
materials.append(material)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': materials,
|
||||
'count': len(materials),
|
||||
'job_number': job_number
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error in get_materials: {e}")
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}), 500
|
||||
Reference in New Issue
Block a user