์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

fastAPI ๋กœ ๋ฐฑ์—”๋“œ ์‹œ์ž‘ํ•˜๊ธฐ (ํ™˜๊ฒฝ ์„ธํŒ…, ํด๋” ๊ตฌ์กฐ, mysql ์‚ฌ์šฉ)

์ฃผ์˜ ๐Ÿฑ 2024. 4. 18. 09:01
728x90
๋ฐ˜์‘ํ˜•

flask๋ฅผ ์จ๋ดค๋‹ค๋ฉด ์กฐ๊ธˆ ์ต์ˆ™ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. 

 

์˜ˆ์‹œ ์ฐธ๊ณ 

https://github.com/tiangolo/full-stack-fastapi-template

 

GitHub - tiangolo/full-stack-fastapi-template: Full stack, modern web application template. Using FastAPI, React, SQLModel, Post

Full stack, modern web application template. Using FastAPI, React, SQLModel, PostgreSQL, Docker, GitHub Actions, automatic HTTPS and more. - tiangolo/full-stack-fastapi-template

github.com

 

๋‚˜์˜ ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์งฐ๋‹ค.

.
โ”œโ”€โ”€ app
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ main.py
โ”‚   โ”œโ”€โ”€ database.py
โ”‚   โ”œโ”€โ”€ models.py
โ”‚   โ”œโ”€โ”€ schemas.py
โ”‚   โ”œโ”€โ”€ crud.py
โ”‚   โ””โ”€โ”€ routers  -(๊ฐ์ข… ๋ผ์šฐํ„ฐ๋“ค)
โ”‚       โ”œโ”€โ”€ __init__.py
โ”‚       โ”œโ”€โ”€ japanese.py
โ”‚       โ””โ”€โ”€ known.py
โ”œโ”€โ”€ tests
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ test_database.py
โ”‚   โ””โ”€โ”€ test_main.py
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ .env
โ””โ”€โ”€ README.md

 


  • requirements.txt

์ผ๋‹จ ๊ฐ€์ƒํ™˜๊ฒฝ์„ ์ƒ์„ฑํ•œ ํ›„, ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋“ค์„ ์„ค์น˜ํ•œ๋‹ค. 

์ด๋“ค์€ requirements.txt๋กœ ๊ด€๋ฆฌํ•œ๋‹ค

fastapi
uvicorn
sqlalchemy
mysqlclient
python-dotenv
pydantic

- FastAPI์™€ ํ•จ๊ป˜ MySQL์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด, mysqlclient๋‚˜ aiomysql ๊ฐ™์€ MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. python-dotenv๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. SQLAlchemy๋Š” ORM์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

  • .env

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์— ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅ

DATABASE_URL=mysql://user:password@localhost/dbname

 

์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ ์„ค๋ช…

  • "app" ํด๋”๋Š” ๋ชจ๋“  ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • app/main.py: FastAPI ์•ฑ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ผ์šฐํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์—์„œ ์•ฑ ์„ค์ •์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • app/database.py: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ๊ณผ ์„ธ์…˜ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์„ค์ •์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. SQLAlchemy๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.
  • app/models.py: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ SQLAlchemy ๋ชจ๋ธ๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ๋Š” japanese ๋ฐ known ํ…Œ์ด๋ธ”์— ํ•ด๋‹นํ•˜๋Š” ๋ชจ๋ธ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • app/schemas.py: ํด๋ผ์ด์–ธํŠธ์™€์˜ ๋ฐ์ดํ„ฐ ๊ตํ™˜์— ์‚ฌ์šฉ๋˜๋Š” Pydantic ๋ชจ๋ธ(์Šคํ‚ค๋งˆ)์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์š”์ฒญ ๋ฐ ์‘๋‹ต ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.
  • app/crud.py: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ CRUD ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋“ค์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋ธ๊ณผ ์Šคํ‚ค๋งˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์บก์Šํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • app/routers/: ๊ฐ ๊ธฐ๋Šฅ๋ณ„๋กœ ๊ฒฝ๋กœ ์—ฐ์‚ฐ์„ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์šฐํ„ฐ ํŒŒ์ผ๋“ค์„ ํฌํ•จํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, japanese ๊ด€๋ จ ๊ฒฝ๋กœ๋Š” japanese.py์—, known ๊ด€๋ จ ๊ฒฝ๋กœ๋Š” known.py์— ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • tests/: FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ, API ์—”๋“œํฌ์ธํŠธ ํ…Œ์ŠคํŠธ ๋“ฑ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • requirements.txt: ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ Python ํŒจํ‚ค์ง€ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, fastapi, uvicorn, pydantic, SQLAlchemy, mysql-connector-python ๋“ฑ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

  • database.py

MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐ์„ ๊ด€๋ฆฌํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. SQLAlchemy create_engine ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—”์ง„์„ ์ƒ์„ฑํ•˜๊ณ , SessionLocal ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ธ์…˜์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import os
from dotenv import load_dotenv

load_dotenv()

DATABASE_URL = os.getenv("DATABASE_URL")

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

Base = declarative_base()
  • models.py

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ์„ SQLAlchemy ORM์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Japanese์™€ Known ํ…Œ์ด๋ธ”์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from sqlalchemy import Column, Integer, String, Date
from .database import Base

class Japanese(Base):
    __tablename__ = "japanese"
    
    id = Column(Integer, primary_key=True, index=True)
    word = Column(String, index=True)
    meaning = Column(String)

class Known(Base):
    __tablename__ = "known"
    
    id = Column(Integer, primary_key=True, index=True)
    word_id = Column(Integer, index=True)
    review_date = Column(Date)

 

๋ฐ˜์‘ํ˜•