✅ 백엔드 구조 개선: - 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: 배포 시 자동 실행 순서 최적화
This commit is contained in:
144
backend/scripts/legacy/generate_complete_schema.py
Normal file
144
backend/scripts/legacy/generate_complete_schema.py
Normal file
@@ -0,0 +1,144 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user