Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
✅ 백엔드 구조 개선: - DatabaseService: 공통 DB 쿼리 로직 통합 - FileUploadService: 파일 업로드 로직 모듈화 및 트랜잭션 관리 개선 - 서비스 레이어 패턴 도입으로 코드 재사용성 향상 ✅ 프론트엔드 컴포넌트 개선: - LoadingSpinner, ErrorMessage, ConfirmDialog 공통 컴포넌트 생성 - 재사용 가능한 컴포넌트 라이브러리 구축 - deprecated/backup 파일들 완전 제거 ✅ 성능 최적화: - optimize_database.py: 핵심 DB 인덱스 자동 생성 - 쿼리 최적화 및 통계 업데이트 자동화 - VACUUM ANALYZE 자동 실행 ✅ 코드 정리: - 개별 SQL 마이그레이션 파일들을 legacy/ 폴더로 정리 - 중복된 마이그레이션 스크립트 정리 - 깔끔하고 체계적인 프로젝트 구조 완성 ✅ 자동 마이그레이션 시스템 강화: - complete_migrate.py: SQLAlchemy 기반 완전한 마이그레이션 - analyze_and_fix_schema.py: 백엔드 코드 분석 기반 스키마 수정 - fix_missing_tables.py: 누락된 테이블/컬럼 자동 생성 - start.sh: 배포 시 자동 실행 순서 최적화
145 lines
6.6 KiB
Python
145 lines
6.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
TK-MP-Project 완전한 DB 스키마 생성 스크립트
|
|
백엔드 SQLAlchemy 모델을 기반으로 PostgreSQL 스키마를 자동 생성
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
from datetime import datetime
|
|
|
|
# 백엔드 모듈 경로 추가
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
from sqlalchemy import create_engine, MetaData
|
|
from sqlalchemy.schema import CreateTable, CreateIndex
|
|
from app.models import Base
|
|
from app.auth.models import User, LoginLog, UserSession, Permission, RolePermission
|
|
|
|
def generate_schema_sql():
|
|
"""SQLAlchemy 모델을 기반으로 완전한 PostgreSQL 스키마 생성"""
|
|
|
|
# 메모리 내 SQLite 엔진 생성 (스키마 생성용)
|
|
engine = create_engine('sqlite:///:memory:', echo=False)
|
|
|
|
# 모든 테이블 생성
|
|
Base.metadata.create_all(engine)
|
|
|
|
# PostgreSQL 방언으로 변환
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
schema_lines = []
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("-- TK-MP-Project 완전한 데이터베이스 스키마")
|
|
schema_lines.append(f"-- 자동 생성일: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
schema_lines.append("-- SQLAlchemy 모델 기반 자동 생성")
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("")
|
|
|
|
# 테이블 생성 SQL 생성
|
|
for table in Base.metadata.sorted_tables:
|
|
create_table_sql = str(CreateTable(table).compile(dialect=postgresql.dialect()))
|
|
|
|
# SQLite -> PostgreSQL 변환
|
|
create_table_sql = create_table_sql.replace('DATETIME', 'TIMESTAMP')
|
|
create_table_sql = create_table_sql.replace('BOOLEAN', 'BOOLEAN')
|
|
create_table_sql = create_table_sql.replace('TEXT', 'TEXT')
|
|
create_table_sql = create_table_sql.replace('JSON', 'JSONB')
|
|
|
|
schema_lines.append(f"-- {table.name} 테이블")
|
|
schema_lines.append(f"CREATE TABLE IF NOT EXISTS {create_table_sql[13:]};") # "CREATE TABLE " 제거
|
|
schema_lines.append("")
|
|
|
|
# 인덱스 생성
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("-- 인덱스 생성")
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("")
|
|
|
|
for table in Base.metadata.sorted_tables:
|
|
for index in table.indexes:
|
|
create_index_sql = str(CreateIndex(index).compile(dialect=postgresql.dialect()))
|
|
schema_lines.append(f"CREATE INDEX IF NOT EXISTS {create_index_sql[13:]};") # "CREATE INDEX " 제거
|
|
|
|
# 필수 데이터 삽입
|
|
schema_lines.append("")
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("-- 필수 기본 데이터 삽입")
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("")
|
|
|
|
# 기본 관리자 계정
|
|
schema_lines.append("-- 기본 관리자 계정 (비밀번호: admin123)")
|
|
schema_lines.append("INSERT INTO users (username, password, name, email, role, access_level, department, position, status) VALUES")
|
|
schema_lines.append("('admin', '$2b$12$ld4LDOW5mxkiRQEkXfMUIep/aIzFleQZ4yoL10ZQkUxGqnkYuhNMW', '시스템 관리자', 'admin@tkmp.com', 'admin', 'admin', 'IT', '시스템 관리자', 'active'),")
|
|
schema_lines.append("('system', '$2b$12$ld4LDOW5mxkiRQEkXfMUIep/aIzFleQZ4yoL10ZQkUxGqnkYuhNMW', '시스템 계정', 'system@tkmp.com', 'system', 'system', 'IT', '시스템 계정', 'active')")
|
|
schema_lines.append("ON CONFLICT (username) DO NOTHING;")
|
|
schema_lines.append("")
|
|
|
|
# 기본 권한 데이터
|
|
schema_lines.append("-- 기본 권한 데이터")
|
|
permissions = [
|
|
('bom.view', 'BOM 조회 권한', 'bom'),
|
|
('bom.create', 'BOM 생성 권한', 'bom'),
|
|
('bom.edit', 'BOM 수정 권한', 'bom'),
|
|
('bom.delete', 'BOM 삭제 권한', 'bom'),
|
|
('project.view', '프로젝트 조회 권한', 'project'),
|
|
('project.create', '프로젝트 생성 권한', 'project'),
|
|
('project.edit', '프로젝트 수정 권한', 'project'),
|
|
('file.upload', '파일 업로드 권한', 'file'),
|
|
('file.download', '파일 다운로드 권한', 'file'),
|
|
('user.view', '사용자 조회 권한', 'user'),
|
|
('user.create', '사용자 생성 권한', 'user'),
|
|
('system.admin', '시스템 관리 권한', 'system')
|
|
]
|
|
|
|
schema_lines.append("INSERT INTO permissions (permission_name, description, module) VALUES")
|
|
for i, (name, desc, module) in enumerate(permissions):
|
|
comma = "," if i < len(permissions) - 1 else ""
|
|
schema_lines.append(f"('{name}', '{desc}', '{module}'){comma}")
|
|
schema_lines.append("ON CONFLICT (permission_name) DO NOTHING;")
|
|
schema_lines.append("")
|
|
|
|
# 완료 메시지
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("-- 스키마 생성 완료")
|
|
schema_lines.append("-- ================================")
|
|
schema_lines.append("")
|
|
schema_lines.append("DO $$")
|
|
schema_lines.append("BEGIN")
|
|
schema_lines.append(" RAISE NOTICE '✅ TK-MP-Project 완전한 데이터베이스 스키마가 성공적으로 생성되었습니다!';")
|
|
schema_lines.append(" RAISE NOTICE '👤 기본 계정: admin/admin123, system/admin123';")
|
|
schema_lines.append(" RAISE NOTICE '🔐 권한 시스템: 모듈별 세분화된 권한 적용';")
|
|
schema_lines.append(" RAISE NOTICE '📊 자동 생성: SQLAlchemy 모델 기반 완전 동기화';")
|
|
schema_lines.append("END $$;")
|
|
|
|
return '\n'.join(schema_lines)
|
|
|
|
def main():
|
|
"""메인 실행 함수"""
|
|
try:
|
|
print("🔄 SQLAlchemy 모델 분석 중...")
|
|
schema_sql = generate_schema_sql()
|
|
|
|
# 스키마 파일 저장
|
|
output_file = os.path.join(os.path.dirname(__file__), '..', '..', 'database', 'init', '00_auto_generated_schema.sql')
|
|
os.makedirs(os.path.dirname(output_file), exist_ok=True)
|
|
|
|
with open(output_file, 'w', encoding='utf-8') as f:
|
|
f.write(schema_sql)
|
|
|
|
print(f"✅ 완전한 DB 스키마가 생성되었습니다: {output_file}")
|
|
print("📋 포함된 내용:")
|
|
print(" - 모든 SQLAlchemy 모델 기반 테이블")
|
|
print(" - 필수 인덱스")
|
|
print(" - 기본 관리자 계정")
|
|
print(" - 기본 권한 데이터")
|
|
print("🚀 배포 시 이 파일이 자동으로 실행됩니다.")
|
|
|
|
except Exception as e:
|
|
print(f"❌ 스키마 생성 실패: {str(e)}")
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|