오늘 계획 : 웹개발 3주차 완강
11일차
< DB개괄 >
들어가기 전.. .
01. DB의 2가지 종류
(1) SQL (RDBMS)
칸이 정해진 엑셀에 데이터를 저장하는 것과 유사
*RDBMS(Relational DataBase Management System) : 관계형 데이터베이스 관리 시스템
RDBMS는 다른 테이블들과 관계를 맺고 모여있는 집합체. Foreing Key를 이용해 테이블 간의 Join을 할 수 있다
EX ) MySQL, MS-SQL 등
🔹 장점:
-사람의 실수 발생이 적어짐(정해진 틀에 데이터가 없을 시 알려줌! => 데이터가 잘 안바뀌는 대기업 비즈니스 등에서 사용)
-데이터를 조금 더 빠르게 가져올 수 있음
-테이블 간 중복 없이 데이터가 저장되어 데이터 수정 시에 용이하다
🔸 단점:
-스키마가 엄격하기 때문에 유연성이 떨어짐
-중복된 데이터가 없기 때문에, JOIN을 사용하여 복잡한 쿼리를 짜야할 수 있다
-비용
(2) NoSQL (Not only SQL)
정형화된 틀이 없음, 테이블 간의 관계를 정의하지 않음, Join 불가능
데이터의 일관성은 포기하고 비용을 고려해서 데이터 분산 저장하는 Scale-Out을 목표로 함
EX ) mongoDB
🔹 장점:
-비즈니스의 유연성 담보
-저장된 데이터 수정이 자유롭고, 새로운 필드 추가 용이
-데이터 분산 용이, Scale-up과 Scale-out 또한 가능
🔸 단점: 데이터 중복 가능성이 있어, 수정 필요 시에 여러 레코드 업데이트 해야하는 단점
추가 상식 적립
Scale-Up :
기존 서버 사양을 upgrade, 시스템을 확장하는 것
하나의 서버 사양을 업그레이드 함 (수직 스케일)
Scale-Out : 서버를 여러 대 추가해서 시스템을 확장하는 것 (수평 스케일)
=> 각 서버에 걸리는 부하를 균등하게 하는 '로드밸런싱' 필수
02. DB의 실체에 관해
-데이터를 쌓고, 데이터를 잘 가져갈 수 있게 하는 프로그램
-사용자 컴퓨터에도 DB설치 가능하지만 요즘에는 Cloud환경에 올려놓음
DB 백업 / 모니터링 등에 용이
-분리된 환경의 DB 구축이 가능한 장점 : 여러가지로 분리된 환경에서 하나의 데이터베이스를 사용할 수 있다.
- 어플리케이션, 프로그램 단위의 DB구축이 가능해서 개별 운용이 가능
-트래픽 예측이 어려운 경우 infrastructrue 구축 비용 또는 리스크 측에서 유리
< mongoDB >
01. mongoDB 연결
mongoDB를 조작하려면
< pymongo >, < dnspython > 2가지 라이브러리가 필요!!
pymongo 기본코드. .
from pymongo import MongoClient
client = MongoClient('여기에 URL 입력') // URL입력 후 password지우고 비번 입력
db = client.dbsparta
1-1) 데이터 넣기 (insert)
mongoDB는 딕셔너리를 넣어줌
doc = {
'name':'영수',
'age':24
}
db.users.insert_one(doc)
1-2) mongoDB Cluster()의 Collections 확인해서 데이터가 들어왔는 지 확인!
02. pymongo로 DB조작
1-1) DB연결 & 데이터 삽입
// 'users'라는 collection에 {'name':'bobby','age':21}를 넣습니다.
db.users.insert_one({'name':'영희','age':30})
db.users.insert_one({'name':'철수','age':20})
db.users.insert_one({'name':'john','age':30})
1-2) 모든 결과 값 보기
=> all_users = list(db.users.find({},{'_id':False})) //{}안에 아무 조건 없는 상태
// 모든 데이터 뽑아보기
all_users = list(db.users.find({},{'_id':False}))
print(all_users[0]) // 0번째 결과값을 보기
print(all_users[0]['name']) // 0번째 결과값의 'name'을 보기
for a in all_users: // 반복문을 돌며 모든 결과값을 보기
print(a)
1-3) 특정 결과 값만 뽑기
user = db.users.find_one({}) // _id 제외 출력 원할 시엔 ,'_id:False'
print(user)
1-4) 수정,조작 하기
db.users.update_one({'name':'영수'},{'$set':{'age':19}})
user = db.users.find_one({'name':'영수'})
print(user)
1-5) 삭제 (거의 안 쓰임)
db.users.delete_one({'name':'영수'})
user = db.users.find_one({'name':'영수'})
print(user)
pymongo의 코드 요약, 사용법
저장 - 예시
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)
한 개 찾기 - 예시
user = db.users.find_one({'name':'bobby'})
여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
all_users = list(db.users.find({},{'_id':False}))
바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
지우기 - 예시
db.users.delete_one({'name':'bobby'})
03. 웹스크래핑 결과 DB에 저장 (insert 이용)
(1) 웹에서 크롤링한 데이터 파일 상단에 pymongo연결코드 삽입
(2) doc를 만들어서 하나씩 insert (list라면 for문 안에 넣어줘야 함)
(3) 실행 후 mongoDB에 저장된 크롤링데이터 확인 가능
04. 3주차 마무리 숙제
지니 사이트 웹스크래핑 (순위 / 곡 제목 / 가수)
- 새로 나온 문법
text[0:2] : 앞에서 2글자만 끊기, strip(), lstrip(), replace('변경 할 문자','변경 후 문자')
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
for tr in trs:
rank = tr.select_one('td.number').text[0:2].strip()
title = tr.select_one('td.info > a.title.ellipsis').text.replace('19금', '').strip()
# if "19금" in title:
# title = "19금 " + tr.select_one('td.info > a.title.ellipsis').text.strip().lstrip('19금').strip()
artist = tr.select_one('td.info > a.artist.ellipsis').text
print(rank,title,artist)
//19금 노래 출력이 잘 나오지 않아서 따로 검색을 해보니 replace 또는 조건문을 걸어서 공백을 없애줄 수 있었다.
12일차
- 오늘 계획 : 웹개발 종합반 백엔드 공부 - Flask
들어가기 전에 .. .
- 백엔드와 프론트엔드 차이점?
-프론트엔드: 사용자가 마주보는 인터페이스
-백엔드: 데이터 저장/관리/전달, 프론트엔드 사용자가 취하는 행동들을 처리(클라이언트 측에서 매끄럽게 작동할 수 있게 함)
프레임워크와 API
-API(Application Programming Interface) : 서로 다른 프로그램에서 요청과 응답을 주고 받을 수 있게 만든 체계, 요청-응답이 잘 이루어지려면 응답(Backend)을 주는 쪽에서 미리 절차를 정해놔야 함(API만들기)
-프레임워크 : 서버를 좀 더 용이하게 만들기 위한 큰 라이브러리 개념
< Flask 프레임워크> :
서버를 구동시켜주는 편한 코드 모음, 사용자 정의 웹서버를 만들 수 있다
01. 서버 만들기
(1) 원하는 폴더로 이동 - 파일 생성(app.py,서버파일)
(2) 새 터미널 생성 - 가상환경 잡기 (python -m venv venv) //맥은 python3 입력
*가상환경 : 프로젝트별로 라이브러리를 담아두는 통.. 프레임워크도 일종의 남이 만든 라이브러리이기 때문에 가상환경을 먼저 잡아야한다.
(3) 터미널에 Flask 설치 (pip install flask)
02. Flask 기초
Flask 시작 코드
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'This is Home!'
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
=> app.py가 flask의 기본적 앱파일명
(1) 저장 후 터미널 링크를 클릭 또는 인터넷 주소창에 localhost:5000 입력
(2) This is Home! 이 뜨면 웹서비스 만들기 성공
-> 내 컴퓨터에서 내가 만든 웹 서비스에 접속한 것 (인터넷 망에 인터넷 서비스를 오픈한 건xxx)
(3) URL 나누기 @app.route('/')를 수정해서 나눔
예시)
@app.route('/')
def home():
return 'This is Home!'
@app.route('/mypage')
def mypage():
return 'This is My Page!'
// route('/')내의 주소 또는 url별 함수명이 중복되지 않도록 주의
(!) 서버 종료 : 터미널 창에서 Ctrl + c
03. Flask에 HTML Linking
Flask 서버를 만들 때 항상 기억해야 할 구조
프로젝트 폴더
ㄴvenv
ㄴapp.py 파일
ㄴtemplates 폴더
ㄴindex.html (클라이언트 파일)
templates 폴더 : HTML파일을 담아두고, 불러오는 역할
1-1) app.py에서 html파일 불러오기
flask의 내장함수 render_template 사용
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
// Flask 백엔드 서버가 돌면서 html을 가져다 줌
04. API 만들기
클라이언트 요청 방식
(1) GET 요청
- (통상적)데이터 조회(Read) 요청 시 사용
- 데이터 전달 : URL뒤에 물음표(?)를 붙여 key=value로 전달
(2) POST 요청
- (통상적) 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청시 사용
- 데이터 전달 : 바로 보이진 않는 HTML
(3) GET/POST 요청에서 클라이언트의 데이터 받는 법 - API를 만들고 사용하는 과정에선 Flask에 있는
request와 jsonify 기능 2가지가 꼭 필요
1-1)GET 요청&GET 요청 확인 Fetch
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/test', methods=['GET']) //GET 요청이 '/test'로 들어옴
def test_get():
title_receive = request.args.get('title_give')
//'title_give'라는 데이터가 있으면, title_receive변수에 넣음
print(title_receive)
return jsonify({'result': 'success', 'msg': '이 요청은 GET!'})
//백엔드에서 프론트엔드 데이터 내려주기
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
1-2)POST 요청&POST 요청 확인 Fetch
app.py
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/test', methods=['POST'])
def test_post():
title_receive = request.form['title_give']
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
templates - index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Document</title>
<script>
function hey() {
let formData = new FormData();
formData.append("title_give", "블랙팬서");
fetch("/test", {
headers: {
Accept: "application / json",
},
method: "POST", body: formData
})
.then(res => res.json())
.then(data => {
console.log(data)
})
}
</script>
</head>
<body>
<h1>제목을 입력합니다.</h1>
<button onclick="hey()">나는 버튼!</button>
</body>
</html>
POST 요청&응답 순서
hey() -> forData("title_give", "블랙팬서") 라는 데이터가 쌓임 -> 데이터를 /test로 fetch가 보냄 -> 백엔드에
POST의 /test에서 받음 -> 'title_give'가 존재해서 request.form['title_give']가 '블랙팬서'로 변경' -> title_receive 출력 -> 마지막으로 return에서 result,msg를 index.html에 있는 fetch console.log(data)에 담긴다 -> console에서 확인가능
+) POST 요청을 하고 새로고침 - 버튼 클릭 - 검사에서 Console 확인 시 오류메세지
Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
검색해보니 API가 JSON으로 읽히지 않은 뜻이었다.
Fetch에서
headers: {
Accept: "application / json",
},
을 명시해주니 해결
'내일배움캠프 > 내일배움단' 카테고리의 다른 글
내일배움단 -개발일지 3주차 (1) (1) | 2023.03.08 |
---|---|
내일배움단 -개발일지 2주차 (2) (0) | 2023.03.08 |
내일배움단 -개발일지 2주차 (1) (0) | 2023.03.08 |
내일배움단 - 개발일지 1주차(3) (2) | 2023.03.08 |
내일배움단 - 개발일지 1주차(2) (0) | 2023.03.08 |