본문 바로가기
주전공/캡스톤디자인과창업프로젝트

여름방학 기록(6): 데이터베이스 초기화 | DB Schema 생성

by 희띠띠 2025. 8. 24.

8/22(금) - DB 초기화 및 CRUD 변환

오늘 한 작업은 다음과 같다.

 

  • SQLAlchemy에서 정의해둔 모든 모델 클래스(Market, Product, Festival, RecommendLog 등)를 불러오고,
  • 그 모델들이 상속한 Base.metadata 안에 테이블 메타정보를 등록하고,
  • Base.metadata.create_all(bind=engine) 으로 SQLite DB(database.db) 안에 실제 테이블 구조를 만든 것

 

🎯 SQLite + SQLAlchemy 연동 및 테이블 생성 기록

이번 작업에서는 FastAPI 백엔드 프로젝트에 SQLite 데이터베이스를 연동하고,
SQLAlchemy ORM 모델을 실제 DB 테이블로 반영(create_all)하는 과정을 진행했다.

 

1️⃣ 데이터베이스 엔진 설정 (app/database.py)

  • SQLite 파일(database.db)을 사용할 수 있도록 SQLAlchemy 엔진과 세션팩토리를 정의.
 
# app/database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# SQLite 파일 DB
SQLALCHEMY_DATABASE_URL = "sqlite:///./database.db"

# SQLite는 멀티스레드 옵션 필요
engine = create_engine(
    SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

 

2️⃣ Base 클래스 정의 (app/models/common_models.py)

  • SQLAlchemy Declarative Base → 모든 모델의 부모 클래스.
 
# app/models/common_models.py
from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
    pass

 

3️⃣ 모델 정의 (app/models/market_models.py 등)

  • 예: 지역, 마켓, 상품, 카테고리 모델
  • Base를 상속받아 테이블 구조를 코드로 정의.
 
# app/models/market_models.py (일부)
from sqlalchemy import Integer, String, ForeignKey, Numeric, DateTime, func
from sqlalchemy.orm import relationship, Mapped, mapped_column
from datetime import datetime
from app.models.common_models import Base

class Market(Base):
    __tablename__ = "markets"
    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
    name: Mapped[str] = mapped_column(String(120), nullable=False, index=True)
    address: Mapped[str] = mapped_column(String(255), nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())

    products = relationship("Product", back_populates="market")

같은 방식으로 festival_models.py, recommend_models.py 파일도 작성

 

4️⃣ 모델 초기화 모듈 (app/models/__init__.py)

  • Base와 모델 모듈을 한 번에 import하여 metadata.create_all 실행 시 모두 반영되도록 설정.
 
# app/models/__init__.py
from app.models.common_models import Base

from .market_models import *
from .festival_models import *
from .recommend_models import *

 

5️⃣ DB 초기화 스크립트 (app/init_db.py)

  • Base.metadata.create_all(bind=engine) 실행 → DB 파일(database.db)에 테이블 생성.
 
# app/init_db.py
from app.database import engine
from app.models.common_models import Base

# 모델 모듈 import → Base.metadata에 등록
import app.models.market_models
import app.models.festival_models
import app.models.recommend_models

def init():
    Base.metadata.create_all(bind=engine)
    print("✅ All tables created.")

if __name__ == "__main__":
    init()

 

6️⃣ 실행 및 결과 확인

실행

 
python -m app.init_db

결과

 
✅ All tables created.

DB 확인 (SQLite CLI)

sqlite3 database.db
.tables
.schema markets
.schema products

 

7️⃣ 경고 메시지 (Pydantic v2 변경)

실행 시 다음 경고가 나타났다:

UserWarning: Valid config keys have changed in V2:
'allow_population_by_field_name' → 'validate_by_name'
'orm_mode' → 'from_attributes'

이는 Pydantic v2에서 설정 키 이름이 바뀐 것을 알리는 경고이며,
이미 Config: from_attributes = True 로 적용했으므로 정상 동작함.

 

✅ 정리

  • 모델(설계도)  DB 테이블(실제 구조) 로 반영 완료.
  • Base.metadata.create_all(bind=engine) 실행 시 database.db 파일이 생성되며, 정의한 모든 테이블이 실제 DB에 만들어짐.
  • 이제 API 라우터에서 SessionLocal을 통해 DB CRUD를 구현할 준비가 됨.

 

👉 이 다음 단계에서는 API 라우터와 서비스 레이어에서 DB CRUD 기능 구현을 진행하면 된다.
예: POST /markets → DB에 새로운 마켓 저장, GET /markets/{id} → 마켓 조회

 

따라서 이 작업은 각자 맡은 기능에 맞춰 다음 회의시간까지 해오기로 했다.

 


 

팀원 코드(추천/축제)와 최대한 호환되게 내 마켓 기능만 DB 기반 CRUD로 바꾸고,

이미 쓰던 엔드포인트/기능(판매자·후기·문의 mock) 은 그대로 유지하는 방향으로 수정본을 정리했다.


festival 쪽은 app.database.get_db를 쓰고 있고, recommend 쪽은 자기들 방식 그대로 두는 게 안전해서, 

market도 festival과 동일하게 app.database.get_db 를 쓰게 구성했다.

 

✅ 변경 요약

  • market_service.py
    • JSON 컬럼(image_urls)과 일치하도록 직렬화/역직렬화 로직 제거 → 리스트 그대로 저장/반환
    • CRUD 쿼리/페이징/정렬은 유지 및 정리
  • market_router.py
    • 목록/상세/생성/수정/삭제(마켓/상품) 을 DB 연동으로 전환
    • 기존 판매자/후기/문의 엔드포인트는 그대로 Mock 유지(스키마/경로/응답 동일)
    • 응답 스키마는 market_models.py의 Pydantic 모델을 그대로 사용
  • 공통코드
    • main.py/database.py는 변경 불필요 (이미 festival과 동일 패턴)