HUTAMS_AUDIO/app/db/models.py

68 lines
3.3 KiB
Python

"""
SQLAlchemy ORM 모델 정의 모듈.
TranscriptionRecord (1) : (N) TranscriptionSegment 관계를 구성합니다.
"""
from datetime import datetime, timezone
from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Text, Boolean
from sqlalchemy.orm import relationship
from app.db.database import Base
class TranscriptionRecord(Base):
"""STT 변환 1건 전체 기록 테이블"""
__tablename__ = "transcription_records"
id = Column(Integer, primary_key=True, index=True)
filename = Column(String(512), nullable=False, comment="원본 업로드 파일명")
full_text = Column(Text, nullable=True, comment="전체 변환 텍스트")
language = Column(String(16), nullable=True, comment="인식된 언어 코드")
base_datetime = Column(DateTime(timezone=True), nullable=True, comment="녹음 시작 절대 시간(KST)")
processing_time_sec = Column(Float, nullable=True, comment="STT 처리 소요 시간 (초)")
audio_duration_sec = Column(Float, nullable=True, comment="오디오 총 길이 (초)")
peak_memory_mb = Column(Float, nullable=True, comment="최대 메모리 점유율 (MB)")
process_speed_x = Column(Float, nullable=True, comment="처리 속도 배수")
# ── LLM 분석 결과 컬럼 ───────────────────────────────────────────────────
title = Column(String(256), nullable=True, comment="LLM 생성 제목")
summary = Column(Text, nullable=True, comment="LLM 생성 1줄 요약")
keywords = Column(String(512), nullable=True, comment="LLM 생성 키워드 (쉼표 구분)")
urgency = Column(String(16), nullable=True, comment="LLM 판단 긴급도 (긴급/일반)")
created_at = Column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
nullable=False,
comment="레코드 생성 시각 (UTC)"
)
# 1:N 관계
segments = relationship(
"TranscriptionSegment",
back_populates="record",
cascade="all, delete-orphan",
lazy="select"
)
class TranscriptionSegment(Base):
"""STT 변환 세그먼트(발화 단위) 테이블"""
__tablename__ = "transcription_segments"
id = Column(Integer, primary_key=True, index=True)
record_id = Column(Integer, ForeignKey("transcription_records.id", ondelete="CASCADE"), nullable=False)
start_sec = Column(Float, nullable=False, comment="발화 시작 시간 (초)")
end_sec = Column(Float, nullable=False, comment="발화 종료 시간 (초)")
text = Column(Text, nullable=True, comment="교정된 발화 텍스트")
speaker = Column(String(32), nullable=True, comment="발화자 식별 결과")
absolute_start_time = Column(String(64), nullable=True, comment="ISO 8601 절대 시작 시간")
absolute_end_time = Column(String(64), nullable=True, comment="ISO 8601 절대 종료 시간")
audio_path = Column(String(512), nullable=True, comment="Opus 압축본 로컬 경로")
is_reviewed = Column(
Boolean,
default=False,
nullable=False,
comment="수동 검토 완료 여부 (불명 세그먼트 후처리 추적용)"
)
# N:1 역참조
record = relationship("TranscriptionRecord", back_populates="segments")