Files
TK-BOM-Project/backend/scripts/06_insert_material_standards_data.py
Hyungi Ahn 5f7a6f0b3a feat: 자재 분류 시스템 개선 및 상세 테이블 추가
- 모든 자재 카테고리별 상세 테이블 생성 (fitting, valve, flange, bolt, gasket, instrument)
- PIPE, FITTING, VALVE 분류 결과를 각 상세 테이블에 저장하는 로직 구현
- 프론트엔드 라우팅 정리 및 BOM 현황 페이지 기능 개선
- 자재확인 페이지 에러 처리 개선

TODO: FLANGE, BOLT, GASKET, INSTRUMENT 저장 로직 추가 필요
2025-07-17 10:44:19 +09:00

462 lines
20 KiB
Python

#!/usr/bin/env python3
"""
자재 규격/재질 기준표 데이터를 DB에 삽입하는 스크립트
기존 materials_schema.py의 딕셔너리 데이터를 DB 테이블로 변환
"""
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker
from app.database import DATABASE_URL
from app.models import (
MaterialStandard, MaterialCategory, MaterialSpecification,
MaterialGrade, MaterialPattern, SpecialMaterial,
SpecialMaterialGrade, SpecialMaterialPattern
)
# 기존 materials_schema.py의 데이터 (일부만 예시로 포함)
MATERIAL_STANDARDS_DATA = {
"ASTM_ASME": {
"name": "미국재질학회",
"country": "USA",
"categories": {
"FORGED_GRADES": {
"name": "단조품",
"specifications": {
"A182": {
"name": "탄소강 단조품",
"material_type": "carbon_alloy",
"manufacturing": "FORGED",
"subtypes": {
"carbon_alloy": {
"manufacturing": "FORGED",
"grades": {
"F1": {
"composition": "0.5Mo",
"temp_max": "482°C",
"applications": "중온용"
},
"F5": {
"composition": "5Cr-0.5Mo",
"temp_max": "649°C",
"applications": "고온용"
},
"F11": {
"composition": "1.25Cr-0.5Mo",
"temp_max": "593°C",
"applications": "일반 고온용"
},
"F22": {
"composition": "2.25Cr-1Mo",
"temp_max": "649°C",
"applications": "고온 고압용"
},
"F91": {
"composition": "9Cr-1Mo-V",
"temp_max": "649°C",
"applications": "초고온용"
}
},
"patterns": [
r"ASTM\s+A182\s+(?:GR\s*)?F(\d+)",
r"A182\s+(?:GR\s*)?F(\d+)",
r"ASME\s+SA182\s+(?:GR\s*)?F(\d+)"
]
},
"stainless": {
"manufacturing": "FORGED",
"grades": {
"F304": {
"composition": "18Cr-8Ni",
"applications": "일반용",
"corrosion_resistance": "보통"
},
"F304L": {
"composition": "18Cr-8Ni-저탄소",
"applications": "용접용",
"corrosion_resistance": "보통"
},
"F316": {
"composition": "18Cr-10Ni-2Mo",
"applications": "내식성",
"corrosion_resistance": "우수"
},
"F316L": {
"composition": "18Cr-10Ni-2Mo-저탄소",
"applications": "용접+내식성",
"corrosion_resistance": "우수"
},
"F321": {
"composition": "18Cr-8Ni-Ti",
"applications": "고온안정화",
"stabilizer": "Titanium"
},
"F347": {
"composition": "18Cr-8Ni-Nb",
"applications": "고온안정화",
"stabilizer": "Niobium"
}
},
"patterns": [
r"ASTM\s+A182\s+F(\d{3}[LH]*)",
r"A182\s+F(\d{3}[LH]*)",
r"ASME\s+SA182\s+F(\d{3}[LH]*)"
]
}
}
},
"A105": {
"name": "탄소강 단조품",
"description": "탄소강 단조품",
"composition": "탄소강",
"applications": "일반 압력용 단조품",
"manufacturing": "FORGED",
"pressure_rating": "150LB ~ 9000LB",
"patterns": [
r"ASTM\s+A105(?:\s+(?:GR\s*)?([ABC]))?",
r"A105(?:\s+(?:GR\s*)?([ABC]))?",
r"ASME\s+SA105"
]
}
}
},
"WELDED_GRADES": {
"name": "용접품",
"specifications": {
"A234": {
"name": "탄소강 용접 피팅",
"material_type": "carbon",
"manufacturing": "WELDED_FABRICATED",
"subtypes": {
"carbon": {
"manufacturing": "WELDED_FABRICATED",
"grades": {
"WPA": {
"yield_strength": "30 ksi",
"applications": "저압용",
"temp_range": "-29°C ~ 400°C"
},
"WPB": {
"yield_strength": "35 ksi",
"applications": "일반용",
"temp_range": "-29°C ~ 400°C"
},
"WPC": {
"yield_strength": "40 ksi",
"applications": "고압용",
"temp_range": "-29°C ~ 400°C"
}
},
"patterns": [
r"ASTM\s+A234\s+(?:GR\s*)?WP([ABC])",
r"A234\s+(?:GR\s*)?WP([ABC])",
r"ASME\s+SA234\s+(?:GR\s*)?WP([ABC])"
]
}
}
}
}
}
}
},
"KS": {
"name": "한국산업표준",
"country": "KOREA",
"categories": {
"PIPE_GRADES": {
"name": "배관용",
"specifications": {
"D3507": {
"name": "배관용 탄소강관",
"description": "배관용 탄소강관",
"manufacturing": "SEAMLESS",
"patterns": [
r"KS\s+D\s*3507\s+SPPS\s*(\d+)"
]
},
"D3583": {
"name": "압력배관용 탄소강관",
"description": "압력배관용 탄소강관",
"manufacturing": "SEAMLESS",
"patterns": [
r"KS\s+D\s*3583\s+STPG\s*(\d+)"
]
}
}
}
}
},
"JIS": {
"name": "일본공업규격",
"country": "JAPAN",
"categories": {
"PIPE_GRADES": {
"name": "배관용",
"specifications": {
"G3452": {
"name": "배관용 탄소강관",
"description": "배관용 탄소강관",
"manufacturing": "WELDED",
"patterns": [
r"JIS\s+G\s*3452\s+SGP"
]
}
}
}
}
}
}
SPECIAL_MATERIALS_DATA = {
"SUPER_ALLOYS": {
"INCONEL": {
"description": "니켈 기반 초합금",
"composition": "Ni-Cr",
"applications": "고온 산화 환경",
"temp_max": "1177°C",
"manufacturing": "FORGED_OR_CAST",
"grades": {
"600": {
"composition": "Ni-Cr",
"temp_max": "1177°C",
"applications": "고온 산화 환경"
},
"625": {
"composition": "Ni-Cr-Mo",
"temp_max": "982°C",
"applications": "고온 부식 환경"
}
},
"patterns": [
r"INCONEL\s*(\d+)"
]
}
},
"TITANIUM": {
"TITANIUM": {
"description": "티타늄 및 티타늄 합금",
"composition": "Ti",
"applications": "화학공정, 항공우주",
"temp_max": "1177°C",
"manufacturing": "FORGED_OR_SEAMLESS",
"grades": {
"1": {
"purity": "상업용 순티타늄",
"strength": "낮음",
"applications": "화학공정"
},
"2": {
"purity": "상업용 순티타늄 (일반)",
"strength": "보통",
"applications": "일반용"
},
"5": {
"composition": "Ti-6Al-4V",
"strength": "고강도",
"applications": "항공우주"
}
},
"patterns": [
r"TITANIUM(?:\s+(?:GR|GRADE)\s*(\d+))?",
r"Ti(?:\s+(?:GR|GRADE)\s*(\d+))?",
r"ASTM\s+B\d+\s+(?:GR|GRADE)\s*(\d+)"
]
}
}
}
def insert_material_standards():
"""자재 규격 데이터를 DB에 삽입"""
engine = create_engine(DATABASE_URL)
Session = sessionmaker(bind=engine)
session = Session()
try:
print("자재 규격 데이터 삽입 시작...")
# 1. 자재 규격 표준 삽입
for standard_code, standard_data in MATERIAL_STANDARDS_DATA.items():
standard = MaterialStandard(
standard_code=standard_code,
standard_name=standard_data["name"],
country=standard_data["country"],
description=f"{standard_data['name']} 규격"
)
session.add(standard)
session.flush() # ID 생성
print(f" - {standard_code} ({standard_data['name']}) 추가됨")
# 2. 카테고리 삽입
for category_code, category_data in standard_data["categories"].items():
category = MaterialCategory(
standard_id=standard.id,
category_code=category_code,
category_name=category_data["name"],
description=f"{category_data['name']} 분류"
)
session.add(category)
session.flush()
print(f" - {category_code} ({category_data['name']}) 추가됨")
# 3. 규격 삽입
for spec_code, spec_data in category_data["specifications"].items():
specification = MaterialSpecification(
category_id=category.id,
spec_code=spec_code,
spec_name=spec_data["name"],
description=spec_data.get("description", ""),
material_type=spec_data.get("material_type"),
manufacturing=spec_data.get("manufacturing"),
pressure_rating=spec_data.get("pressure_rating")
)
session.add(specification)
session.flush()
print(f" - {spec_code} ({spec_data['name']}) 추가됨")
# 4. 패턴 삽입
if "patterns" in spec_data:
for i, pattern in enumerate(spec_data["patterns"]):
pattern_obj = MaterialPattern(
specification_id=specification.id,
pattern=pattern,
description=f"{spec_code} 패턴 {i+1}",
priority=i+1
)
session.add(pattern_obj)
# 5. 등급 삽입 (subtypes가 있는 경우)
if "subtypes" in spec_data:
for subtype_name, subtype_data in spec_data["subtypes"].items():
# subtypes의 grades 처리
if "grades" in subtype_data:
for grade_code, grade_data in subtype_data["grades"].items():
grade = MaterialGrade(
specification_id=specification.id,
grade_code=grade_code,
composition=grade_data.get("composition"),
applications=grade_data.get("applications"),
temp_max=grade_data.get("temp_max"),
temp_range=grade_data.get("temp_range"),
yield_strength=grade_data.get("yield_strength"),
corrosion_resistance=grade_data.get("corrosion_resistance"),
stabilizer=grade_data.get("stabilizer"),
base_grade=grade_data.get("base_grade")
)
session.add(grade)
print(f" - {grade_code} 등급 추가됨")
# 5. 등급 삽입 (직접 grades가 있는 경우)
elif "grades" in spec_data:
for grade_code, grade_data in spec_data["grades"].items():
grade = MaterialGrade(
specification_id=specification.id,
grade_code=grade_code,
composition=grade_data.get("composition"),
applications=grade_data.get("applications"),
temp_max=grade_data.get("temp_max"),
temp_range=grade_data.get("temp_range"),
yield_strength=grade_data.get("yield_strength"),
corrosion_resistance=grade_data.get("corrosion_resistance"),
stabilizer=grade_data.get("stabilizer"),
base_grade=grade_data.get("base_grade")
)
session.add(grade)
print(f" - {grade_code} 등급 추가됨")
session.commit()
print("자재 규격 데이터 삽입 완료!")
except Exception as e:
session.rollback()
print(f"오류 발생: {e}")
raise
finally:
session.close()
def insert_special_materials():
"""특수 재질 데이터를 DB에 삽입"""
engine = create_engine(DATABASE_URL)
Session = sessionmaker(bind=engine)
session = Session()
try:
print("특수 재질 데이터 삽입 시작...")
for material_type, materials in SPECIAL_MATERIALS_DATA.items():
for material_name, material_data in materials.items():
# 특수 재질 추가
special_material = SpecialMaterial(
material_type=material_type,
material_name=material_name,
description=material_data.get("description", ""),
composition=material_data.get("composition"),
applications=material_data.get("applications"),
temp_max=material_data.get("temp_max"),
manufacturing=material_data.get("manufacturing")
)
session.add(special_material)
session.flush()
print(f" - {material_name} ({material_type}) 추가됨")
# 등급 추가
if "grades" in material_data:
for grade_code, grade_data in material_data["grades"].items():
grade = SpecialMaterialGrade(
material_id=special_material.id,
grade_code=grade_code,
composition=grade_data.get("composition"),
applications=grade_data.get("applications"),
temp_max=grade_data.get("temp_max"),
strength=grade_data.get("strength"),
purity=grade_data.get("purity"),
corrosion=grade_data.get("corrosion")
)
session.add(grade)
print(f" - {grade_code} 등급 추가됨")
# 패턴 추가
if "patterns" in material_data:
for i, pattern in enumerate(material_data["patterns"]):
pattern_obj = SpecialMaterialPattern(
material_id=special_material.id,
pattern=pattern,
description=f"{material_name} 패턴 {i+1}",
priority=i+1
)
session.add(pattern_obj)
session.commit()
print("특수 재질 데이터 삽입 완료!")
except Exception as e:
session.rollback()
print(f"오류 발생: {e}")
raise
finally:
session.close()
def main():
"""메인 실행 함수"""
print("자재 규격/재질 기준표 DB 데이터 삽입 시작")
print("=" * 50)
# 1. 자재 규격 데이터 삽입
insert_material_standards()
print("\n" + "=" * 50)
# 2. 특수 재질 데이터 삽입
insert_special_materials()
print("\n" + "=" * 50)
print("모든 데이터 삽입 완료!")
if __name__ == "__main__":
main()