DB 구조 변경
3월 이후 기존 DB와 비교했을 때, 새로 생성된 테이블이나 삭제된 테이블이 많습니다.
또한 기존 테이블도 특정 컬럼이 추가되거나 수정되는 등의 변화가 생겼습니다.
그로 인해 모델 코드 또한 전체적으로 수정되었습니다.
모델 코드
모델 코드는 models 디렉터리에 저장 중입니다.
API 관련
API의 경우 전체적으로 모델 코드가 이전과 거의 그대로입니다.
기존 구조를 유지하지만, 테이블명이나 컬럼명이 약간 수정된 정도의 변화만 있습니다.
사용자 및 프로젝트 관련
from sqlalchemy import Column, Integer, String, Date, Text, ForeignKey, JSON, TIMESTAMP, func
from database.base import Base
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import ARRAY, BYTEA
from pgvector.sqlalchemy import Vector
class ProjectInfoBase(Base):
__tablename__ = "project_info_base"
id = Column(Integer, primary_key=True, autoincrement=True)
project_id = Column(Integer, ForeignKey("project_table.project_id", ondelete="CASCADE"), nullable=False)
user_email = Column(String(255), ForeignKey("user_table.email", ondelete="CASCADE"), nullable=False)
file_url = Column(Text, nullable=True)
#vector_memory = Column(Vector(1536), nullable=True)
upload_at = Column(TIMESTAMP, default=func.current_timestamp())
# 외래 키 관계 설정
project = relationship("Project", backref="info")
user = relationship("User", backref="project_info")
class InfoList(Base):
__tablename__ = "info_list"
id = Column(Integer, primary_key=True, autoincrement=True)
infobase_id = Column(Integer, ForeignKey("project_info_base.id", ondelete="CASCADE"), nullable=False)
content = Column(Text)
vector_memory = Column(Vector(1536))
upload_at = Column(TIMESTAMP, default=func.current_timestamp())
infobase = relationship("ProjectInfoBase", backref="info_list")
Vector는 전부 1536 차원으로 저장합니다.
지식베이스의 경우 원본 파일에 대한 정보를 담고 있는 Project Info Base 테이블과,
파일 내의 정보를 벡터로 변환한 Vector DB를 따로 생성하여 2개의 테이블로 관리하도록 수정했습니다.
마이그레이션
from typing import Sequence, Union
from pgvector.sqlalchemy import Vector
from alembic import op
import sqlalchemy as sa
revision: str = 'f09e385c1e15'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table('conversation_session',
sa.Column('id', sa.String(length=255), nullable=False),
sa.Column('session_title', sa.String(length=255), nullable=False),
sa.Column('project_id', sa.Integer(), nullable=True),
sa.Column('user_email', sa.String(length=255), nullable=True),
sa.Column('register_at', sa.TIMESTAMP(), nullable=True),
sa.ForeignKeyConstraint(['project_id'], ['project_table.project_id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['user_email'], ['user_table.email'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_table('conversation_logs',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('session_id', sa.String(length=255), nullable=False),
sa.Column('project_id', sa.Integer(), nullable=False),
sa.Column('user_email', sa.String(length=255), nullable=False),
sa.Column('message_role', sa.String(length=255), nullable=False),
sa.Column('conversation', sa.Text(), nullable=False),
sa.Column('vector_memory', Vector(dim=1536), nullable=True),
sa.Column('request_at', sa.TIMESTAMP(), nullable=True),
sa.ForeignKeyConstraint(['project_id'], ['project_table.project_id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['session_id'], ['conversation_session.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['user_email'], ['user_table.email'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_table('info_list',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('infobase_id', sa.Integer(), nullable=False),
sa.Column('content', sa.Text(), nullable=True),
sa.Column('vector_memory', Vector(dim=1536), nullable=True),
sa.Column('upload_at', sa.TIMESTAMP(), nullable=True),
sa.ForeignKeyConstraint(['infobase_id'], ['project_info_base.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
Alembic에서 자동으로 마이그레이션 코드를 생성해주지만,
처음 생성할 때에는 파이썬이 pgVector를 제대로 처리하지 못하기 때문에 에러가 발생할 수 있습니다.
에러가 발생할 경우, 위의 코드처럼 Alembic이 생성해준 코드에서 Vector 관련 타입을 전부 VECTOR(dim=1536)로 변경하면 해결됩니다.
alembic upgrade head
이후 이 명령어를 터미널에서 실행하면 DB에 테이블이 전부 생성됩니다.
ERD

PostgreSQL의 PG Admin 화면에서 확인 가능한 데이터베이스의 ERD입니다.
Schemas의 public 우클릭 후 ‘ERD for Schema’를 통해 확인 가능합니다.