Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 249 additions & 0 deletions app/db/init_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,255 @@ def initialize_database():
"""
)

# database_annotation 테이블 생성
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS database_annotation (
id VARCHAR(64) PRIMARY KEY NOT NULL,
db_profile_id VARCHAR(64) NOT NULL,
database_name VARCHAR(255) NOT NULL,
description TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (db_profile_id) REFERENCES db_profile(id) ON DELETE CASCADE
);
"""
)
# database_annotation 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_database_annotation_updated_at
BEFORE UPDATE ON database_annotation
FOR EACH ROW
BEGIN
UPDATE database_annotation SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

# table_annotation 테이블 생성
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS table_annotation (
id VARCHAR(64) PRIMARY KEY NOT NULL,
database_annotation_id VARCHAR(64) NOT NULL,
table_name VARCHAR(255) NOT NULL,
description TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (database_annotation_id) REFERENCES database_annotation(id) ON DELETE CASCADE
);
"""
)
# table_annotation 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_table_annotation_updated_at
BEFORE UPDATE ON table_annotation
FOR EACH ROW
BEGIN
UPDATE table_annotation SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

# column_annotation 테이블 생성 (단일 컬럼 스펙 전용)
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS column_annotation (
id VARCHAR(64) PRIMARY KEY NOT NULL,
table_annotation_id VARCHAR(64) NOT NULL,
column_name VARCHAR(255) NOT NULL,
-- 데이터 타입 (원본 DB의 타입 문자열을 그대로 저장; 예: BIGINT, TEXT, TIMESTAMP)
data_type VARCHAR(64),
-- NULL 허용 여부 (1:true, 0:false)
is_nullable INTEGER NOT NULL DEFAULT 1,
-- 기본값(리터럴 또는 표현식; 문자열 형태로 저장)
default_value TEXT,
-- 단일 컬럼 기준 CHECK 제약 표현(예: "value > 0")
check_expression TEXT,
-- 컬럼 순서
ordinal_position INTEGER,
-- 설명
description TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (table_annotation_id) REFERENCES table_annotation(id) ON DELETE CASCADE
);
"""
)
# column_annotation 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_column_annotation_updated_at
BEFORE UPDATE ON column_annotation
FOR EACH ROW
BEGIN
UPDATE column_annotation SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

# table_relationship 테이블 생성
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS table_relationship (
id VARCHAR(64) PRIMARY KEY NOT NULL,
database_annotation_id VARCHAR(64) NOT NULL,
from_table_id VARCHAR(64) NOT NULL,
to_table_id VARCHAR(64) NOT NULL,
relationship_type VARCHAR(32) NOT NULL,
description TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (database_annotation_id) REFERENCES database_annotation(id) ON DELETE CASCADE,
FOREIGN KEY (from_table_id) REFERENCES table_annotation(id) ON DELETE CASCADE,
FOREIGN KEY (to_table_id) REFERENCES table_annotation(id) ON DELETE CASCADE
);
"""
)
# table_relationship 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_table_relationship_updated_at
BEFORE UPDATE ON table_relationship
FOR EACH ROW
BEGIN
UPDATE table_relationship SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

# ---------------------------------------------------------------------
# 복합 제약(Primary/Unique/ForeignKey/Check) 메타데이터 테이블 생성
# - 여러 컬럼을 묶는 제약을 '그룹' 단위로 관리
# - UI 배지/목록은 이 테이블들에서 파생 계산
# ---------------------------------------------------------------------

# table_constraint 테이블 생성 (제약 그룹 본체)
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS table_constraint (
id VARCHAR(64) PRIMARY KEY NOT NULL,
table_annotation_id VARCHAR(64) NOT NULL,
-- PRIMARY_KEY | UNIQUE | FOREIGN_KEY | CHECK
constraint_type VARCHAR(16) NOT NULL,
-- DB 제약명(선택)
name VARCHAR(255),
-- CHECK 제약식 등 (FK/PK/UNIQUE에는 NULL 가능)
expression TEXT,
-- FOREIGN KEY 전용: 참조 테이블명
ref_table VARCHAR(255),
-- FOREIGN KEY 전용: 액션
on_update_action VARCHAR(16),
on_delete_action VARCHAR(16),
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (table_annotation_id) REFERENCES table_annotation(id) ON DELETE CASCADE
);
"""
)
# table_constraint 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_table_constraint_updated_at
BEFORE UPDATE ON table_constraint
FOR EACH ROW
BEGIN
UPDATE table_constraint SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

# constraint_column 테이블 생성 (제약 그룹 ↔ 컬럼 매핑)
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS constraint_column (
id VARCHAR(64) PRIMARY KEY NOT NULL,
constraint_id VARCHAR(64) NOT NULL,
column_annotation_id VARCHAR(64) NOT NULL,
-- 복합 제약 내 컬럼 순서(1, 2, 3, ...)
position INTEGER,
-- FOREIGN KEY 전용: 참조 테이블의 대응 컬럼명 (복합 FK 매핑)
referenced_column_name VARCHAR(255),
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (constraint_id) REFERENCES table_constraint(id) ON DELETE CASCADE,
FOREIGN KEY (column_annotation_id) REFERENCES column_annotation(id) ON DELETE CASCADE
);
"""
)
# constraint_column 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_constraint_column_updated_at
BEFORE UPDATE ON constraint_column
FOR EACH ROW
BEGIN
UPDATE constraint_column SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

# ---------------------------------------------------------------------
# 인덱스(복합 포함) 메타데이터 테이블 생성
# - DB 인덱스명을 보존하고, 컬럼 순서를 기록
# ---------------------------------------------------------------------

# index_annotation 테이블 생성 (인덱스 그룹 본체)
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS index_annotation (
id VARCHAR(64) PRIMARY KEY NOT NULL,
table_annotation_id VARCHAR(64) NOT NULL,
name VARCHAR(255), -- DB 인덱스명(선택)
is_unique INTEGER NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (table_annotation_id) REFERENCES table_annotation(id) ON DELETE CASCADE
);
"""
)
# index_annotation 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_index_annotation_updated_at
BEFORE UPDATE ON index_annotation
FOR EACH ROW
BEGIN
UPDATE index_annotation SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

# index_column 테이블 생성 (인덱스 그룹 ↔ 컬럼 매핑)
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS index_column (
id VARCHAR(64) PRIMARY KEY NOT NULL,
index_id VARCHAR(64) NOT NULL,
column_annotation_id VARCHAR(64) NOT NULL,
-- 인덱스 내 컬럼 순서(1, 2, 3, ...)
position INTEGER,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (index_id) REFERENCES index_annotation(id) ON DELETE CASCADE,
FOREIGN KEY (column_annotation_id) REFERENCES column_annotation(id) ON DELETE CASCADE
);
"""
)
# index_column 테이블의 updated_at을 자동으로 업데이트하는 트리거
cursor.execute(
"""
CREATE TRIGGER IF NOT EXISTS update_index_column_updated_at
BEFORE UPDATE ON index_column
FOR EACH ROW
BEGIN
UPDATE index_column SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
"""
)

conn.commit()

except sqlite3.Error as e:
Expand Down