기술 FASTAPI_데이터베이스 연동
1단계 파일구조
├── templates
│ ├── detail_sample.html #샘플 표시 방식
│ ├── list_sample.html #샘플 표시 방식
│ └── user_detail.html #유저 개인 정보 표시
| └── user_list.html #유저 개인 정보 표시
└── db.py
└── model.py
└── mainlist.py
└── model.py
사용
SQL Alchemy - SQL 사용하기위해 쓰는 프로그램 언어 Starlette 경랑 아스키 프레임 워크
2. 자세한 파일 설명
db.py 데이터베이스 연동하는 코드이다
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
user_name = 데이터베이스 유저 이름
user_pwd = 데이터 유저 이름
db_host = 데이터 베이스 주소
db_name = 데이터 베이스 이름
DATABASE = 'mysql://%s:%s@%s/%s?charset=utf8' % (
user_name,
user_pwd,
db_host,
db_name,
)
ENGINE = create_engine(
DATABASE,
encoding="utf-8",
echo=True
)
session = scoped_session(
sessionmaker(
autocommit=False,
autoflush=False,
bind=ENGINE
)
)
Base = declarative_base()
Base.query = session.query_property()
model.py 데이터 베이스 모델을 정의하는 코드이다
# coding: utf-8
from sqlalchemy import Column, Integer, String
from pydantic import BaseModel
from db import Base
from db import ENGINE
class UserTable(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(30), nullable=True)
age = Column(Integer)
class User(BaseModel):
id : int
name : str
age : int
def main():
# Table 없으면 생성
Base.metadata.create_all(bind=ENGINE)
if __name__ == "__main__":
main()
mainlist.py 기본 FastAPi 틀이다
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from typing import List
from starlette.middleware.cors import CORSMiddleware
from db import session
from model import UserTable, User
templates = Jinja2Templates(directory="templates")
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
async def root():
return {"message": "/users 에서 사용자관리"}
# ----------API 정의------------
@app.get("/users", response_class=HTMLResponse) #기본 화면 입력 보여주기
async def read_users(request: Request):
print("read_users >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
context = {}
users = session.query(UserTable).all()
context['request'] = request
context['users'] = users
return templates.TemplateResponse("user_list.html", context)
@app.get("/users/{user_id}", response_class=HTMLResponse) #특정 유저 값 읽어오기
async def read_user(request: Request, user_id: int):
print("read_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
context = {}
user = session.query(UserTable).filter(UserTable.id == user_id).first()
print(user.name)
context['name'] = user.name
context['age'] = user.age
context['request'] = request
return templates.TemplateResponse("user_detail.html", context)
@app.post("/users")
async def create_user(users: User): #유저값 추가하기
print("create_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
# data = await request.json()
userlist = list(users)
uname = userlist[1][1]
uage = userlist[2][1]
user = UserTable()
user.name = uname
user.age = uage
session.add(user)
session.commit()
return { 'result_msg': f'{uname} Registered...' }
@app.put("/users")
async def modify_users(users: User): #유저값 수정하기
print("modify_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
userlist = list(users)
uid = userlist[0][1]
uname = userlist[1][1]
uage = userlist[2][1]
user = session.query(UserTable).filter(UserTable.id == uid).first()
user.name = uname
user.age = uage
session.commit()
return { 'result_msg': f"{uname} updated..." }
@app.delete("/users")
async def delete_users(users: User): #유저값 삭제하기
print("delete_user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
userlist = list(users)
uid = userlist[0][1]
user = session.query(UserTable).filter(UserTable.id == uid).delete()
session.commit()
return {'result_msg': f"User deleted..."}
user_list.html 데이터 베이스에서 받은 데이터를 CRUD 해주는 페이지이다
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User list</title>
<script>
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
var xhr;
// Ajax로 등록
function postUser() {
var uname = document.getElementById('username_').value;
var uage = parseInt(document.getElementById('userage_').value);
var data = { id: 0, name: uname, age: uage };
var jsonstr = JSON.stringify(data);
//alert(jsonstr);
//return false;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var data = xhr.responseText;
var obj = JSON.parse(data);
var node = document.createElement("DIV");
var textnode = document.createTextNode(uname + " - " + uage + " added...");
node.appendChild(textnode);
document.getElementById("usertable").appendChild(node);
//alert(obj.name + " registered...");
}
};
xhr.open("POST", "/users");
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(jsonstr);
}
// Ajax로 수정
function putUser(elem) {
var userid = parseInt(elem.getAttribute('userid'));
var uname = document.getElementById('username_'+userid).value;
var uage = parseInt(document.getElementById('userage_'+userid).value);
var data = { id: userid, name: uname, age: uage }
var jsonstr = JSON.stringify(data);
//alert(jsonstr);
//return false;
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var data = xhr.responseText;
var obj = JSON.parse(data);
//alert(uname + " modified...");
document.getElementById('username_'+userid).style.color = "#FF6600";
document.getElementById('userage_'+userid).style.color = "#FF6600";
}
};
xhr.open("PUT", "/users");
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(jsonstr);
}
// Ajax로 삭제
function deleteUser(userid) {
if (confirm("삭제 하시겠습니까?") == false) {
return false;
}
var data = { id: userid, name: '', age: 0 }
var jsonstr = JSON.stringify(data);
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var data = xhr.responseText;
var obj = JSON.parse(data);
document.getElementById('userbox_'+userid).remove();
//alert(obj.result_msg);
}
};
xhr.open("DELETE", "/users");
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(jsonstr);
}
</script>
</head>
<body>
<div style="padding:10px;">
<a href="/">HOME</a>
</div>
<h1 style="padding:10px;">User list</h1>
<div style="margin:20px 0">
<input type="text" id="username_" value="사용자" />
<input type="text" id="userage_" value="1" />
<button onclick="postUser()">등록</button>
</div>
<div id="usertable">
<table width="100%" border="1" cellpadding="0" cellspacing="0">
<tr style="padding:10px;border-top:solid 1px #3388cc;">
<td>
No user...
</td>
</tr>
</table>
</div>
</body>
</html>
참고
- https://www.youtube.com/watch?v=N8i4GcRRkV8&t=1230s
- 해당 관련으로 FastAPI 관련 설명이 동영상으로 설명이 잘 되어 있다.
- http://cop.projectcafe.kr:3100/gidatalab 31번쨰 참고
댓글남기기