Python / FastAPI + өгөгдлийн сан

FastAPI + өгөгдлийн сан

Одоогийн API-д өгөгдлийг санах ойн dict-д хадгалж байсан — server дахин эхлэхэд бүгд арилна. Бодит програм өгөгдлийг өгөгдлийн санд байнга хадгалдаг. Энэ хичээлд Python-д суулгалттай ирдэг SQLite ашиглан FastAPI-тай холбоно — нэмэлт тохиргоо, сервер шаардахгүй.

SQLite ба sqlite3 модуль

SQLite нь нэг файлд бүх өгөгдлийг хадгалдаг жижиг өгөгдлийн сан. sqlite3 нь Python стандарт модуль тул суулгах шаардлагагүй.

python
import sqlite3

# Холбогдох (файл байхгүй бол автоматаар үүсгэнэ)
холболт = sqlite3.connect("сургалт.db")
cursor = холболт.cursor()

# Хүснэгт үүсгэх
cursor.execute("""
    CREATE TABLE IF NOT EXISTS сурагчид (
        id      INTEGER PRIMARY KEY AUTOINCREMENT,
        нэр     TEXT    NOT NULL,
        и_мэйл TEXT    UNIQUE NOT NULL,
        xp      INTEGER DEFAULT 0
    )
""")

холболт.commit()
холболт.close()
print("Өгөгдлийн сан бэлэн болов")

FastAPI-тай хослуулах

Өгөгдлийн сантай ажиллах функцүүдийг тусад нь файлд байрлуулах нь кодыг цэвэр байлгана:

python
# database.py
import sqlite3

DB_FILE = "сургалт.db"

def холболт_авах():
    conn = sqlite3.connect(DB_FILE)
    conn.row_factory = sqlite3.Row   # dict шиг хандах боломж
    return conn

def хүснэгт_үүсгэх():
    with холболт_авах() as conn:
        conn.execute("""
            CREATE TABLE IF NOT EXISTS сурагчид (
                id      INTEGER PRIMARY KEY AUTOINCREMENT,
                нэр     TEXT NOT NULL,
                и_мэйл TEXT UNIQUE NOT NULL,
                xp      INTEGER DEFAULT 0
            )
        """)
python
# main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from database import холболт_авах, хүснэгт_үүсгэх

app = FastAPI()
хүснэгт_үүсгэх()   # server эхлэхэд хүснэгт бэлэн болгоно

class СурагчОруулга(BaseModel):
    нэр: str
    и_мэйл: str

@app.post("/сурагч", status_code=201)
def сурагч_нэмэх(оруулга: СурагчОруулга):
    with холболт_авах() as conn:
        try:
            cursor = conn.execute(
                "INSERT INTO сурагчид (нэр, и_мэйл) VALUES (?, ?)",
                (оруулга.нэр, оруулга.и_мэйл)
            )
            conn.commit()
            return {"id": cursor.lastrowid, "нэр": оруулга.нэр}
        except Exception:
            raise HTTPException(status_code=400, detail="И-мэйл давхардсан байна")

? тавих нь SQL injection халдлагаас хамгаалдаг — утгыг шууд мөрт оруулж болохгүй.

Өгөгдөл унших ба шинэчлэх

python
@app.get("/сурагчид")
def сурагчид_жагсаах():
    with холболт_авах() as conn:
        мөрүүд = conn.execute(
            "SELECT * FROM сурагчид ORDER BY xp DESC"
        ).fetchall()
        return [dict(мөр) for мөр in мөрүүд]

@app.get("/сурагч/{id}")
def сурагч_авах(id: int):
    with холболт_авах() as conn:
        мөр = conn.execute(
            "SELECT * FROM сурагчид WHERE id = ?", (id,)
        ).fetchone()
        if мөр is None:
            raise HTTPException(status_code=404, detail="Сурагч олдсонгүй")
        return dict(мөр)

@app.patch("/сурагч/{id}/xp")
def xp_нэмэх(id: int, хэмжээ: int = 10):
    with холболт_авах() as conn:
        шинэчилсэн = conn.execute(
            "UPDATE сурагчид SET xp = xp + ? WHERE id = ?",
            (хэмжээ, id)
        ).rowcount
        conn.commit()
        if шинэчилсэн == 0:
            raise HTTPException(status_code=404, detail="Сурагч олдсонгүй")
        return {"амжилт": True, "нэмсэн_xp": хэмжээ}

conn.row_factory = sqlite3.Row тохируулсан учраас dict(мөр) хөрвүүлэлт ажиллана — FastAPI JSON болгон буцааж чадна.

Файлын бүтэц

Бодит FastAPI + SQLite төслийн зөв бүтэц:

код
миний-api/
├── main.py          ← FastAPI app, endpoint-үүд
├── database.py      ← холболт, хүснэгт үүсгэх
├── сургалт.db       ← SQLite файл (git-д оруулахгүй)
├── requirements.txt
└── .gitignore

SQLite нь хөгжүүлэлт болон жижиг аппликейшнд маш тохиромжтой. Илүү том ачааллын хувьд PostgreSQL руу шилжихэд SQL синтакс ихэнхдээ адилхан тул сурсан зүйлээ шууд ашиглаж болно.

Дараагийн хичээлд:

Тест бичих (pytest) — кодынхоо зөв ажиллагааг автоматаар шалгах, pytest ашиглан FastAPI endpoint тест хэрхэн бичихийг сурна.