博客搭建学习游戏blog搭建笔记day2
中生代将后端的模拟数据替换为真实的数据库。#
我们一步一步来创建这些文件。
第一步:创建数据库连接 (database.py)
这个文件负责设置与数据库的连接,并管理数据库会话。
在 backend 目录下创建一个新文件 database.py,并填入以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # backend/database.py
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker
# 数据库URL,"sqlite:///./blog.db" 表示在当前目录下创建一个名为 blog.db 的SQLite数据库文件 SQLALCHEMY_DATABASE_URL = "sqlite:///./blog.db"
# 创建SQLAlchemy引擎 engine = create_engine( SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False} # check_same_thread只在SQLite需要 )
# 创建一个数据库会话类 SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# 创建一个Base类,我们之后创建的数据库模型将继承这个类 Base = declarative_base()
|
第二步:创建数据库模型 (models.py)
这个文件定义了你的数据在数据库中是如何存储的。每个类都代表一张数据表。
在 backend 目录下创建 models.py 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13
| # backend/models.py
from sqlalchemy import Column, Integer, String from .database import Base # 从我们刚创建的database.py中导入Base
# 创建一个Post模型,它将映射到数据库中的'posts'表 class Post(Base): __tablename__ = "posts" # 表名
# 定义表的列 id = Column(Integer, primary_key=True, index=True) # id,主键,并建立索引 title = Column(String, index=True) # 标题,并建立索引 content = Column(String) # 内容
|
第三步:创建Pydantic数据模式 (schemas.py)
为什么需要这个文件? models.py 定义了数据在数据库中的样子,而 schemas.py 定义了数据在 API 中应该是什么样子。这样做可以将数据库层和API层解耦,更安全、更清晰。
在 backend 目录下创建 schemas.py 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # backend/schemas.py
from pydantic import BaseModel
# 定义基础的Post模式 class PostBase(BaseModel): title: str content: str | None = None # content是可选的
# 用于创建Post的模式,继承自PostBase class PostCreate(PostBase): pass # 创建时不需要额外字段
# 用于从API读取(返回)Post的模式 class Post(PostBase): id: int # 读取时需要返回id
class Config: orm_mode = True # 这个配置告诉Pydantic模型可以从ORM对象中读取数据
|
第四步:创建数据库操作函数 (crud.py)
我们将所有直接与数据库交互的函数(增删改查)都放在这个文件里。
在 backend 目录下创建 crud.py 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # backend/crud.py
from sqlalchemy.orm import Session from . import models, schemas # 导入模型和模式
# 根据ID查询单个Post def get_post(db: Session, post_id: int): return db.query(models.Post).filter(models.Post.id == post_id).first()
# 查询所有Post(支持分页) def get_posts(db: Session, skip: int = 0, limit: int = 100): return db.query(models.Post).offset(skip).limit(limit).all()
# 创建一个新的Post def create_post(db: Session, post: schemas.PostCreate): # 用schemas.PostCreate的数据创建一个models.Post实例 db_post = models.Post(title=post.title, content=post.content) db.add(db_post) # 添加到会话 db.commit() # 提交到数据库以保存 db.refresh(db_post) # 刷新实例以获取数据库生成的数据(如ID) return db_post
|
第五步:整合到主应用 (main.py)
现在,我们来改造 main.py,让它使用我们刚刚创建的所有模块。
用以下内容完全替换 backend/main.py 里的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| # backend/main.py
from fastapi import Depends, FastAPI, HTTPException from sqlalchemy.orm import Session
# 从同级目录导入我们创建的模块 from . import crud, models, schemas from .database import SessionLocal, engine
# 根据我们的模型在数据库中创建表 models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# --- CORS配置 (保持不变) --- from fastapi.middleware.cors import CORSMiddleware origins = ["http://localhost:5173", "http://127.0.0.1:5173"] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # --- CORS配置结束 ---
# --- 依赖项 --- # 定义一个依赖项,它为每个请求创建一个新的数据库会话 def get_db(): db = SessionLocal() try: yield db finally: db.close()
# --- API 端点 ---
# 创建一个新Post # response_model=schemas.Post 告诉FastAPI响应体将符合Post模式 @app.post("/api/posts/", response_model=schemas.Post) def create_new_post(post: schemas.PostCreate, db: Session = Depends(get_db)): # 直接调用crud函数 return crud.create_post(db=db, post=post)
# 获取所有Post @app.get("/api/posts/", response_model=list[schemas.Post]) def read_posts(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)): posts = crud.get_posts(db, skip=skip, limit=limit) return posts
# 获取单个Post @app.get("/api/posts/{post_id}", response_model=schemas.Post) def read_post(post_id: int, db: Session = Depends(get_db)): db_post = crud.get_post(db, post_id=post_id) if db_post is None: raise HTTPException(status_code=404, detail="Post not found") return db_post
|
第六步:验证成果
1.启动后端服务:在你的后端终端,像之前一样启动服务:
1
| uvicorn main:app --reload
|
当你第一次运行此命令后,你会发现在 backend 目录下多出了一个 blog.db 文件。这就是你的SQLite数据库!models.Base.metadata.create_all(bind=engine) 这行代码已经自动为你创建了posts表。
- 拓展 python包管理
为了让Python更明确地将一个文件夹识别为“包”,最佳实践是在这个文件夹里放一个空的 文件。init.py
这个文件不需要任何内容,它的存在本身就是一个信号。
2.检查前端:刷新你的浏览器 。页面现在应该是空的,只显示标题,因为数据库里还没有任何文章。这是正常的。http://localhost:5173
3.创建第一篇文章:
打开浏览器的一个新标签页,访问 http://127.0.0.1:8000/docs。 这是FastAPI自动生成的交互式API文档。
找到绿色的 路径,点击它展开。POST /api/posts/
点击右上角的 “Try it out” 按钮。
在 “Request body” 中输入你的第一篇文章内容,例如:
1 2 3 4
| { "title": "我的第一篇数据库文章", "content": "内容存储在SQLite中!" }
|
点击下方的 “Execute” 按钮。
最终验证:如果执行成功(Response code 200),现在回到你的前端页面 http://localhost:5173 并刷新它。