14강 / 20강

Flask — 요청을 받아 DB를 여는 문

풀스택 뼈대 ② 판단하는 층

Flask — 요청을 받아 DB를 여는 문
Flask는 요청을 받아 SQL을 실행하고 결과를 돌려주는 파이썬 웹 서버입니다.

앞 강에서 "브라우저가 서버에 요청한다"고 했죠. 그런데 서버 쪽에서는 누가 그 요청을 받을까요?

그 역할을 하는 프로그램이 웹 프레임워크이고, 파이썬에서 가장 배우기 쉬운 것이 Flask(플라스크)입니다.

우리가 만들 것의 전체 뼈대

이제부터 마지막 강까지, 우리는 DBMS 위에 올라선 풀스택 웹앱 하나를 짓습니다. 건물처럼 네 개의 층으로 되어 있어요. 각 층은 딱 한 가지 일만 합니다.

4층🎨 Bootstrap

보기 좋게 — 색·여백·카드·반응형

3층📄 Jinja2

데이터를 HTML로 — 반복·조건·상속

2층🧪 Flask

요청을 받고 판단 — 라우트·검증·계산

1층🗄️ SQLite3

진실을 보관 — 표·타입·트랜잭션

1층은 지난 강에서 지었습니다. 오늘은 2층이에요. 1층이 없으면 나머지 세 층은 모래 위의 집입니다. 그래서 데이터베이스가 먼저였던 거예요.

세상에서 가장 짧은 웹 서버

from flask import Flask
app = Flask(__name__)

@app.route("/")            # 주소 "/" 로 요청이 오면
def hello():               # 이 함수를 실행해서
    return "안녕하세요!"    # 이 글자를 돌려준다

app.run(port=5000)

단 6줄입니다. @app.route(...)를 라우트(route)라고 부르는데, "이 주소는 이 함수가 담당"이라는 이정표예요.

🎮 라우터 실험실 — 주소를 바꿔 가며 보내 보세요

아래는 진짜 라우팅 규칙으로 주소를 맞춰 보고, 여러분의 연습 DB에 실제 SQL을 실행하는 미니 서버입니다. 주소 한 글자만 바꿔도 담당 함수가 달라져요.

  • /api/products/2 와 /api/products/999 를 비교해 보세요. 하나는 200, 하나는 404입니다.
  • /api/products/abc — 왜 404일까요? <int:pid> 는 숫자만 받기 때문입니다.
  • 주소는 그대로 두고 메서드만 DELETE로 바꿔 /api/products 에 보내 보세요. 405가 뜹니다. "주소는 있는데 그 방법은 안 받는다"는 뜻이에요.
  • POST로 상품을 등록한 뒤 GET /api/products 로 확인해 보세요. 진짜로 늘어나 있습니다.
  • / 와 /api/products 를 비교해 보세요. 같은 SELECT인데 하나는 HTML, 하나는 JSON입니다. 마지막 한 줄만 다르거든요.
라우터 실험실 — URL이 함수를 고르고, 함수가 SQL을 실행합니다
불러오는 중…

Flask가 DB를 여는 방법

라우트 함수 안에서 SQLite3를 열고, SQL을 실행하고, 결과를 받습니다. 세 줄이면 돼요.

import sqlite3
from flask import Flask, render_template

app = Flask(__name__)

def db():
    conn = sqlite3.connect("shop.db")
    conn.row_factory = sqlite3.Row    # 결과를 딕셔너리처럼 다루기
    return conn

@app.route("/")
def product_list():
    conn = db()
    rows = conn.execute("SELECT * FROM product ORDER BY id").fetchall()
    conn.close()
    return render_template("products.html", products=rows)   # ← 3층으로 넘긴다

마지막 줄이 오늘의 핵심입니다. render_template은 "이 데이터를 가지고 화면을 만들어 줘"라고 3층(Jinja2)에게 넘기는 말이에요.

🖥️브라우저GET /
→
🧪Flask어느 함수가 처리할지 결정
→
🗄️SQLite3SELECT * FROM product
← 완성된 HTML ←

또 하나의 길 — JSON API

서버가 완성된 화면(HTML) 대신 데이터만(JSON) 돌려줄 수도 있습니다. 앱이나 자바스크립트가 화면을 직접 그릴 때 쓰는 방식이에요.

from flask import jsonify, request

@app.route("/api/products")                 # 데이터만 돌려주기
def api_products():
    conn = db()
    rows = conn.execute("SELECT * FROM product").fetchall()
    conn.close()
    return jsonify([dict(r) for r in rows])

@app.route("/api/products", methods=["POST"])
def api_add():
    name  = request.json["name"]
    price = request.json["price"]
    conn = db()
    cur = conn.execute("INSERT INTO product (name, price) VALUES (?, ?)", (name, price))
    conn.commit(); conn.close()
    return jsonify({"id": cur.lastrowid}), 201
render_template (서버가 화면까지)
  • 첫 화면이 빠르게 보인다
  • 검색엔진이 내용을 읽는다
  • 배우기 쉽다 — 우리가 갈 길
jsonify (데이터만)
  • 모바일 앱과 같은 서버를 쓸 수 있다
  • 화면 일부만 새로 그리기 좋다
  • 프론트엔드 코드가 따로 필요

둘 다 DB에서 읽어 오는 부분은 완전히 같습니다. 달라지는 건 마지막 한 줄뿐이에요.

🤔 확인 문제
Flask 라우트 함수가 render_template("products.html", products=rows) 를 돌려주면 무슨 일이 일어날까요?