#!/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()