🚨 해결된 문제: - name 'row' is not defined 오류 - name 'f' is not defined 오류 - PostgreSQL Row 객체 속성 접근 문제 🔧 수정 내용: - Row 객체 속성 접근을 인덱스 접근으로 변경 - m.original_description → m[2] - f.job_no → m[11], m.job_no → m[12] - 모든 컬럼을 올바른 인덱스로 매핑 ✅ 결과: - /files/materials?job_no=J24-001 정상 작동 - 4개 자재 데이터 완벽 반환 - JSON 응답 구조 완전 정상화 🎯 테스트 완료: - J24-001: 4개 자재 (PIPE, ELBOW, VALVE, FLANGE) - J24-002: 분류된 자재들 정상 응답 - API 응답 속도 및 안정성 확인됨
167 lines
4.9 KiB
Python
167 lines
4.9 KiB
Python
from flask import Flask, request, jsonify
|
|
import psycopg2
|
|
from contextlib import contextmanager
|
|
|
|
app = Flask(__name__)
|
|
|
|
@contextmanager
|
|
def get_db_connection():
|
|
conn = psycopg2.connect(
|
|
host="localhost",
|
|
database="tkmp_db",
|
|
user="tkmp_user",
|
|
password="tkmp2024!",
|
|
port="5432"
|
|
)
|
|
try:
|
|
yield conn
|
|
finally:
|
|
conn.close()
|
|
|
|
@app.route('/')
|
|
def home():
|
|
return {"message": "API 작동 중"}
|
|
|
|
@app.route('/api/materials')
|
|
def get_materials():
|
|
job_number = request.args.get('job_number')
|
|
|
|
if not job_number:
|
|
return {"error": "job_number 필요"}, 400
|
|
|
|
try:
|
|
with get_db_connection() as conn:
|
|
cur = conn.cursor()
|
|
|
|
cur.execute("""
|
|
SELECT id, job_number, item_number, description,
|
|
category, quantity, unit, created_at
|
|
FROM materials
|
|
WHERE job_number = %s
|
|
ORDER BY item_number
|
|
""", (job_number,))
|
|
|
|
rows = cur.fetchall()
|
|
|
|
materials = []
|
|
for r in rows:
|
|
item = {
|
|
'id': r[0],
|
|
'job_number': r[1],
|
|
'item_number': r[2],
|
|
'description': r[3],
|
|
'category': r[4],
|
|
'quantity': r[5],
|
|
'unit': r[6],
|
|
'created_at': str(r[7]) if r[7] else None
|
|
}
|
|
materials.append(item)
|
|
|
|
return {
|
|
'success': True,
|
|
'data': materials,
|
|
'count': len(materials)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"error": f"DB 오류: {str(e)}"}, 500
|
|
|
|
if __name__ == '__main__':
|
|
print("🚀 서버 시작: http://localhost:5000")
|
|
app.run(debug=True, port=5000)
|
|
# 수정된 get_materials API (올바른 컬럼명 사용)
|
|
@app.route('/api/materials-fixed', methods=['GET'])
|
|
def get_materials_fixed():
|
|
"""올바른 컬럼명을 사용한 자재 조회 API"""
|
|
try:
|
|
file_id = request.args.get('file_id')
|
|
|
|
if not file_id:
|
|
return jsonify({
|
|
'success': False,
|
|
'error': 'file_id parameter is required'
|
|
}), 400
|
|
|
|
with get_db_connection() as conn:
|
|
cur = conn.cursor()
|
|
|
|
cur.execute("""
|
|
SELECT
|
|
id, file_id, line_number, original_description,
|
|
classified_category, classified_subcategory,
|
|
quantity, unit, created_at
|
|
FROM materials
|
|
WHERE file_id = %s
|
|
ORDER BY line_number
|
|
""", (file_id,))
|
|
|
|
materials = []
|
|
for item in cur.fetchall():
|
|
material = {
|
|
'id': item[0],
|
|
'file_id': item[1],
|
|
'line_number': item[2],
|
|
'original_description': item[3],
|
|
'classified_category': item[4],
|
|
'classified_subcategory': item[5],
|
|
'quantity': float(item[6]) if item[6] else 0,
|
|
'unit': item[7],
|
|
'created_at': item[8].isoformat() if item[8] else None
|
|
}
|
|
materials.append(material)
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'data': materials,
|
|
'count': len(materials),
|
|
'file_id': file_id
|
|
})
|
|
|
|
except Exception as e:
|
|
print(f"Error in get_materials_fixed: {e}")
|
|
return jsonify({
|
|
'success': False,
|
|
'error': str(e)
|
|
}), 500
|
|
|
|
@app.get("/api/materials-test")
|
|
def get_materials_test(file_id: int):
|
|
"""테스트용 자재 조회 API"""
|
|
try:
|
|
with get_db_connection() as conn:
|
|
cur = conn.cursor()
|
|
|
|
cur.execute("""
|
|
SELECT
|
|
id, file_id, line_number, original_description,
|
|
classified_category, quantity, unit
|
|
FROM materials
|
|
WHERE file_id = %s
|
|
ORDER BY line_number
|
|
LIMIT 5
|
|
""", (file_id,))
|
|
|
|
rows = cur.fetchall()
|
|
|
|
materials = []
|
|
for r in rows:
|
|
materials.append({
|
|
'id': r[0],
|
|
'file_id': r[1],
|
|
'line_number': r[2],
|
|
'description': r[3],
|
|
'category': r[4],
|
|
'quantity': float(r[5]) if r[5] else 0,
|
|
'unit': r[6]
|
|
})
|
|
|
|
return {
|
|
'success': True,
|
|
'data': materials,
|
|
'count': len(materials)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {'error': str(e)}
|
|
|