관계형 DB(RDBMS)가 아닌 NOSQL(NOT ONLY SQL)계열에서 사용하는 ORM이라고 생각하면 된다. 그렇다면 ORM이 무엇일까?
객체 지향 언어가 실용화 된지가 오래이다. 객체 지향언어는 기본적으로 모든 데이터가 객체를 기반으로 작동한다.
그 객체는 일시적이기 때문에, 객체를 오래 저장하고 다음에도 사용하기 위해서 '데이터 베이스'가 생겼다.
만약 RDBMS라면 SQL쿼리를 사용하여 객체의 RETRIEVE, STORE, UPDATE를 수행한다. 즉, 개발자가 저장하고 싶은 객체를 기반으로 SQL쿼리 문을 만들어서(EX : insert into student values(25, 'navin', 'java') 데이터 베이스에 요청하여야했다.
하지만 만약에 어떤 마법사가 객체만을 보고 SQL쿼리 문을 만들어 준다면? 그것이 ORM이다.
대표적인 ORM의 예로, .NET의 경우 ENTITY FRAMEWORK, DJANGO의 경우에도 자체 ORM TOOL이 존재한다.
beanie==1.11.0
fastapi==0.78.0
uvicorn==0.17.6
├── app
│ ├── __init__.py
│ ├── main.py
│ └── server
│ ├── app.py
│ ├── database.py
│ ├── models
│ └── routes
└── requirements.txt
import uvicorn
if __name__ == "__main__":
uvicorn.run("server.app:app", host="0.0.0.0", port=8000, reload=True)
uvicorn 서버에 포트 8000으로 작동하게 했고 reload= True를 통해 수정할때마다 reload 되게 했다.
from fastapi import FastAPI
app = FastAPI()
@app.get("/", tags=["Root"])
async def read_root() -> dict:
return {"message": "Welcome to your beanie powered app!"}
추가한 후에 python app/main.py를 통해 실행,
http://localhost:8000로 접속하면
{"message": "Welcome to your beanie powered app!"}
여기까지가 가장 기본적인 fastapi와 Uvicorn을 이용한 웹 서버이다.
먼저 db를 연결하기 위해서 스키마 구조부터 짜준다.
from datetime import datetime
from beanie import Document
from pydantic import BaseModel
from typing import Optional
class ProductReview(Document):
name: str
product: str
rating: float
review: str
date: datetime = datetime.now()
class Settings:
name = "product_review"
class Config:
schema_extra = {
"example": {
"name": "Abdulazeez",
"product": "TestDriven TDD Course",
"rating": 4.9,
"review": "Excellent course!",
"date": datetime.now()
}
}
class UpdateProductReview(BaseModel):
name: Optional[str]
product: Optional[str]
rating: Optional[float]
review: Optional[str]
date: Optional[datetime]
class Config:
schema_extra = {
"example": {
"name": "Abdulazeez Abdulazeez",
"product": "TestDriven TDD Course",
"rating": 5.0,
"review": "Excellent course!",
"date": datetime.now()
}
}
우리는 beanie를 이용할거기 때문에 pydantic의 BaseModel이 아니라 beanie의 document를 include한 후 그것을 상속하는 스키마 클래스를 짜준다. (beanie의 document 또한 BaseModel로 구동되기 때문에 (powered by) Swagger docs(api test해주는 기능인거 같음) 에서 example data를 제공할 수 있다고 함.)
그냥 document를 상속 받기만 하면 database collection과 연결되지 않는다. Settings 라는 sub class를 선언해준다.
Swagger docs에서 example schema를 제공하기 위해
Config 클래스를 선언한후 schema_extra변수를 선언해준다.
from beanie import init_beanie
import motor.motor_asyncio
from app.server.models.product_review import ProductReview
async def init_db():
client = motor.motor_asyncio.AsyncIOMotorClient(
"mongodb://localhost:27017/productreviews"
)
await init_beanie(database=client.db_name, document_models=[ProductReview])
init_db()안에서 client를 설정해준후, init_beanie method를 통해 연결해준다.
main에
@app.on_event("startup")
async def start_db():
await init_db()
추가하여 startup 시 바로 실행 되도록 했다.
참고 :