feat: jobs 테이블 및 더미 데이터 생성
- PostgreSQL jobs 테이블 스키마 생성 - 더미 프로젝트 데이터 2개 추가 (J24-001, J24-002) - 엔지니어링 업계 구조 반영 (엔드유저-클라이언트-EPC) - 가상환경 경로 이슈 해결 방법 문서화
This commit is contained in:
36
backend/scripts/01_create_jobs_table.sql
Normal file
36
backend/scripts/01_create_jobs_table.sql
Normal file
@@ -0,0 +1,36 @@
|
||||
-- jobs 테이블 생성
|
||||
CREATE TABLE IF NOT EXISTS jobs (
|
||||
-- 기본 정보
|
||||
job_no VARCHAR(50) PRIMARY KEY,
|
||||
job_name VARCHAR(200) NOT NULL,
|
||||
|
||||
-- 계약 관계 (핵심)
|
||||
client_name VARCHAR(100) NOT NULL,
|
||||
|
||||
-- 프로젝트 정보
|
||||
end_user VARCHAR(100),
|
||||
epc_company VARCHAR(100),
|
||||
project_site VARCHAR(200),
|
||||
|
||||
-- 상업 정보
|
||||
contract_date DATE,
|
||||
delivery_date DATE,
|
||||
delivery_terms VARCHAR(100),
|
||||
|
||||
-- 상태 관리 (핵심)
|
||||
status VARCHAR(20) DEFAULT '진행중',
|
||||
delivery_completed_date DATE,
|
||||
project_closed_date DATE,
|
||||
|
||||
-- 관리 정보
|
||||
description TEXT,
|
||||
created_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT true
|
||||
);
|
||||
|
||||
-- 인덱스 생성
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_client ON jobs(client_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_jobs_created_at ON jobs(created_at);
|
||||
19
backend/scripts/02_modify_files_table.sql
Normal file
19
backend/scripts/02_modify_files_table.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
-- files 테이블에 job_no 컬럼 추가 및 project_id 대체
|
||||
|
||||
-- 새 컬럼 추가
|
||||
ALTER TABLE files ADD COLUMN IF NOT EXISTS job_no VARCHAR(50);
|
||||
|
||||
-- 외래키 제약조건 추가 (MySQL/PostgreSQL 문법)
|
||||
-- MySQL의 경우:
|
||||
-- ALTER TABLE files ADD CONSTRAINT fk_files_job_no FOREIGN KEY (job_no) REFERENCES jobs(job_no);
|
||||
|
||||
-- PostgreSQL의 경우:
|
||||
-- ALTER TABLE files ADD CONSTRAINT fk_files_job_no FOREIGN KEY (job_no) REFERENCES jobs(job_no);
|
||||
|
||||
-- SQLite의 경우는 외래키 제약조건을 나중에 추가하기 어려우므로 생략
|
||||
|
||||
-- 인덱스 생성
|
||||
CREATE INDEX IF NOT EXISTS idx_files_job_no ON files(job_no);
|
||||
|
||||
-- 기존 project_id 컬럼은 일단 유지 (호환성을 위해)
|
||||
-- 나중에 완전 이전 후 DROP 할 예정
|
||||
108
backend/scripts/03_insert_dummy_data.py
Normal file
108
backend/scripts/03_insert_dummy_data.py
Normal file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
더미 프로젝트 데이터 생성 스크립트
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime, date
|
||||
from sqlalchemy import create_engine, text
|
||||
|
||||
# 프로젝트 루트를 Python path에 추가
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
def create_dummy_jobs():
|
||||
"""더미 Job 데이터 생성"""
|
||||
|
||||
# 간단한 SQLite 연결 (실제 DB 설정에 맞게 수정)
|
||||
try:
|
||||
# 실제 프로젝트의 database.py 설정 사용
|
||||
from app.database import engine
|
||||
print("✅ 데이터베이스 연결 성공")
|
||||
except ImportError:
|
||||
# 직접 연결 (개발용)
|
||||
DATABASE_URL = "sqlite:///./test.db" # 실제 DB URL로 변경
|
||||
engine = create_engine(DATABASE_URL)
|
||||
print("⚠️ 직접 데이터베이스 연결")
|
||||
|
||||
# 더미 데이터 정의
|
||||
dummy_jobs = [
|
||||
{
|
||||
'job_no': 'J24-001',
|
||||
'job_name': '울산 SK에너지 정유시설 증설 배관공사',
|
||||
'client_name': '삼성엔지니어링',
|
||||
'end_user': 'SK에너지',
|
||||
'epc_company': '삼성엔지니어링',
|
||||
'project_site': '울산광역시 온산공단 SK에너지 정유공장',
|
||||
'contract_date': '2024-03-15',
|
||||
'delivery_date': '2024-08-30',
|
||||
'delivery_terms': 'FOB 울산항',
|
||||
'status': '진행중',
|
||||
'description': '정유시설 증설을 위한 배관 자재 공급 프로젝트. 고온고압 배관 및 특수 밸브 포함.',
|
||||
'created_by': 'admin'
|
||||
},
|
||||
{
|
||||
'job_no': 'J24-002',
|
||||
'job_name': '포스코 광양 제철소 배관 정비공사',
|
||||
'client_name': '포스코',
|
||||
'end_user': '포스코',
|
||||
'epc_company': None,
|
||||
'project_site': '전남 광양시 포스코 광양제철소',
|
||||
'contract_date': '2024-04-02',
|
||||
'delivery_date': '2024-07-15',
|
||||
'delivery_terms': 'DDP 광양제철소 현장',
|
||||
'status': '진행중',
|
||||
'description': '제철소 정기 정비를 위한 배관 부품 교체. 내열성 특수강 배관 포함.',
|
||||
'created_by': 'admin'
|
||||
}
|
||||
]
|
||||
|
||||
try:
|
||||
with engine.connect() as conn:
|
||||
# 기존 더미 데이터 삭제 (개발용)
|
||||
print("🧹 기존 더미 데이터 정리...")
|
||||
conn.execute(text("DELETE FROM jobs WHERE job_no IN ('J24-001', 'J24-002')"))
|
||||
|
||||
# 새 더미 데이터 삽입
|
||||
print("📝 더미 데이터 삽입 중...")
|
||||
|
||||
for job in dummy_jobs:
|
||||
insert_query = text("""
|
||||
INSERT INTO jobs (
|
||||
job_no, job_name, client_name, end_user, epc_company,
|
||||
project_site, contract_date, delivery_date, delivery_terms,
|
||||
status, description, created_by, is_active
|
||||
) VALUES (
|
||||
:job_no, :job_name, :client_name, :end_user, :epc_company,
|
||||
:project_site, :contract_date, :delivery_date, :delivery_terms,
|
||||
:status, :description, :created_by, :is_active
|
||||
)
|
||||
""")
|
||||
|
||||
conn.execute(insert_query, {**job, 'is_active': True})
|
||||
print(f"✅ {job['job_no']}: {job['job_name']}")
|
||||
|
||||
# 커밋
|
||||
conn.commit()
|
||||
|
||||
# 결과 확인
|
||||
result = conn.execute(text("""
|
||||
SELECT job_no, job_name, client_name, status
|
||||
FROM jobs
|
||||
WHERE job_no IN ('J24-001', 'J24-002')
|
||||
"""))
|
||||
jobs = result.fetchall()
|
||||
|
||||
print(f"\n🎉 총 {len(jobs)}개 더미 Job 생성 완료!")
|
||||
print("\n📋 생성된 더미 데이터:")
|
||||
for job in jobs:
|
||||
print(f" • {job[0]}: {job[1]} ({job[2]}) - {job[3]}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 더미 데이터 생성 실패: {e}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
create_dummy_jobs()
|
||||
19
backend/scripts/create_jobs.sql
Normal file
19
backend/scripts/create_jobs.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE IF NOT EXISTS jobs (
|
||||
job_no VARCHAR(50) PRIMARY KEY,
|
||||
job_name VARCHAR(200) NOT NULL,
|
||||
client_name VARCHAR(100) NOT NULL,
|
||||
end_user VARCHAR(100),
|
||||
epc_company VARCHAR(100),
|
||||
project_site VARCHAR(200),
|
||||
contract_date DATE,
|
||||
delivery_date DATE,
|
||||
delivery_terms VARCHAR(100),
|
||||
status VARCHAR(20) DEFAULT '진행중',
|
||||
delivery_completed_date DATE,
|
||||
project_closed_date DATE,
|
||||
description TEXT,
|
||||
created_by VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT true
|
||||
);
|
||||
81
backend/scripts/insert_dummy_jobs.py
Normal file
81
backend/scripts/insert_dummy_jobs.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os
|
||||
from datetime import datetime, date
|
||||
|
||||
# 프로젝트 루트를 Python path에 추가
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
try:
|
||||
from app.database import engine
|
||||
from sqlalchemy import text
|
||||
print("✅ 데이터베이스 연결 성공")
|
||||
except ImportError as e:
|
||||
print(f"❌ 임포트 실패: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
def insert_dummy_data():
|
||||
dummy_jobs = [
|
||||
{
|
||||
'job_no': 'J24-001',
|
||||
'job_name': '울산 SK에너지 정유시설 증설 배관공사',
|
||||
'client_name': '삼성엔지니어링',
|
||||
'end_user': 'SK에너지',
|
||||
'epc_company': '삼성엔지니어링',
|
||||
'project_site': '울산광역시 온산공단',
|
||||
'contract_date': '2024-03-15',
|
||||
'delivery_date': '2024-08-30',
|
||||
'delivery_terms': 'FOB 울산항',
|
||||
'description': '정유시설 증설을 위한 배관 자재 공급',
|
||||
'created_by': 'admin'
|
||||
},
|
||||
{
|
||||
'job_no': 'J24-002',
|
||||
'job_name': '포스코 광양 제철소 배관 정비공사',
|
||||
'client_name': '포스코',
|
||||
'end_user': '포스코',
|
||||
'epc_company': None,
|
||||
'project_site': '전남 광양시 포스코 제철소',
|
||||
'contract_date': '2024-04-02',
|
||||
'delivery_date': '2024-07-15',
|
||||
'delivery_terms': 'DDP 광양제철소',
|
||||
'description': '제철소 정기 정비용 배관 부품',
|
||||
'created_by': 'admin'
|
||||
}
|
||||
]
|
||||
|
||||
try:
|
||||
with engine.connect() as conn:
|
||||
# 기존 더미 데이터 삭제
|
||||
conn.execute(text("DELETE FROM jobs WHERE job_no IN ('J24-001', 'J24-002')"))
|
||||
|
||||
# 새 데이터 삽입
|
||||
for job in dummy_jobs:
|
||||
query = text("""
|
||||
INSERT INTO jobs (
|
||||
job_no, job_name, client_name, end_user, epc_company,
|
||||
project_site, contract_date, delivery_date, delivery_terms,
|
||||
description, created_by, is_active
|
||||
) VALUES (
|
||||
:job_no, :job_name, :client_name, :end_user, :epc_company,
|
||||
:project_site, :contract_date, :delivery_date, :delivery_terms,
|
||||
:description, :created_by, :is_active
|
||||
)
|
||||
""")
|
||||
|
||||
conn.execute(query, {**job, 'is_active': True})
|
||||
print(f"✅ {job['job_no']}: {job['job_name']}")
|
||||
|
||||
conn.commit()
|
||||
print(f"\n🎉 {len(dummy_jobs)}개 더미 Job 생성 완료!")
|
||||
|
||||
# 확인
|
||||
result = conn.execute(text("SELECT job_no, job_name, client_name FROM jobs"))
|
||||
for row in result:
|
||||
print(f" • {row[0]}: {row[1]} ({row[2]})")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 오류: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
insert_dummy_data()
|
||||
73
backend/scripts/setup_database.py
Normal file
73
backend/scripts/setup_database.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
전체 데이터베이스 설정 및 더미 데이터 생성
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from sqlalchemy import create_engine, text
|
||||
|
||||
# 프로젝트 루트를 Python path에 추가
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
def setup_database():
|
||||
"""데이터베이스 전체 설정"""
|
||||
|
||||
try:
|
||||
from app.database import engine
|
||||
print("✅ 기존 데이터베이스 연결 사용")
|
||||
except ImportError:
|
||||
# 개발용 직접 연결
|
||||
DATABASE_URL = "sqlite:///./test.db"
|
||||
engine = create_engine(DATABASE_URL)
|
||||
print("⚠️ 개발용 SQLite 연결")
|
||||
|
||||
try:
|
||||
with engine.connect() as conn:
|
||||
print("🏗️ 1단계: jobs 테이블 생성...")
|
||||
|
||||
# jobs 테이블 생성 SQL 실행
|
||||
with open('scripts/01_create_jobs_table.sql', 'r', encoding='utf-8') as f:
|
||||
sql_commands = f.read().split(';')
|
||||
for command in sql_commands:
|
||||
command = command.strip()
|
||||
if command:
|
||||
conn.execute(text(command))
|
||||
|
||||
print("✅ jobs 테이블 생성 완료")
|
||||
|
||||
print("🔧 2단계: files 테이블 수정...")
|
||||
|
||||
# files 테이블 수정 (선택적)
|
||||
try:
|
||||
with open('scripts/02_modify_files_table.sql', 'r', encoding='utf-8') as f:
|
||||
sql_commands = f.read().split(';')
|
||||
for command in sql_commands:
|
||||
command = command.strip()
|
||||
if command and not command.startswith('--'):
|
||||
conn.execute(text(command))
|
||||
print("✅ files 테이블 수정 완료")
|
||||
except Exception as e:
|
||||
print(f"⚠️ files 테이블 수정 건너뜀: {e}")
|
||||
|
||||
# 커밋
|
||||
conn.commit()
|
||||
|
||||
print("🎯 3단계: 더미 데이터 생성...")
|
||||
# 더미 데이터 스크립트 실행
|
||||
exec(open('scripts/03_insert_dummy_data.py').read())
|
||||
|
||||
print("\n🎉 전체 설정 완료!")
|
||||
print("\n📋 다음 단계:")
|
||||
print(" 1. API 서버 실행")
|
||||
print(" 2. GET /jobs 엔드포인트 테스트")
|
||||
print(" 3. Job 선택 후 BOM 파일 업로드")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 데이터베이스 설정 실패: {e}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup_database()
|
||||
Reference in New Issue
Block a user