迷你城市世界
62.53M · 2026-03-23
入门python时,如果想先搭一个后端项目Demo练手,我建议使用FastAPI作为框架。
很多新手第一次接触 FastAPI 时,常见困惑不是“接口怎么写”,而是:
api、schemas、db 分别是干什么的?这篇文章我会结合一个真实的 FastAPI 小项目,带你快速看懂它的目录结构、每个模块的职责,以及它们之间是怎么配合工作的。文章最后还会贴上完整代码,方便直接上手练习。
这是一个简单的用户管理接口项目,提供了几个基础功能:
虽然功能不复杂,但它已经具备了一个后端项目的基本分层思路,非常适合新手拿来入门。
当前项目的核心目录如下:
app
├── __init__.py
├── main.py
├── requirements.txt
├── run.py
├── api
│ └── user.py
├── core
│ └── config.py
├── db
│ ├── __init__.py
│ ├── database.py
│ └── models.py
└── schemas
└── user.py
如果你是第一次看这种结构,可以先这样理解:
main.py:应用主入口,负责创建 FastAPI 实例、注册路由run.py:启动脚本,用来运行项目api/:放接口路由,也就是你写 get/post/delete/put 的地方schemas/:放请求和响应的数据结构,用 Pydantic 做数据校验db/:放数据库相关代码,包括数据库连接和 ORM 模型core/:放全局配置、公共设置requirements.txt:项目依赖列表对于新手来说,先记住一句话就够了:
FastAPI 常见项目结构,本质上就是把“接口、数据校验、数据库、配置”分开放。
main.py:项目总入口main.py 的职责通常有 3 个:
在这个项目里,它做了这些事:
FastAPI(title="Demo API")user 路由/ 测试接口也就是说,main.py 更像整个项目的“总装配中心”。
run.py:项目启动脚本run.py 的作用是帮你更方便地启动服务。
它内部调用了 uvicorn.run(...),指定了:
app.main:app127.0.0.18001这样你就不用每次手动敲很长的 uvicorn 命令了。
api/user.py:接口层这里是项目里最接近“业务功能”的部分,主要负责定义接口。
当前文件里有 4 个接口:
POST /users/add:新增用户GET /users/list:查询用户列表DELETE /users/{user_id}:删除用户PUT /users/{user_id}:更新用户这一层主要处理的是:
你可以把它理解成“前端和后端交互的入口”。
schemas/user.py:数据校验层FastAPI 很重要的一个特点,就是它和 Pydantic 配合得很好。
这个文件里定义了几个数据模型:
UserBase:用户基础字段UserCreate:创建用户时使用UserUpdate:更新用户时使用User:返回给前端的用户数据结构为什么要单独拆一个 schemas 目录?
因为数据库模型和接口入参/出参不一定完全一样。
把它们分开写,会更清晰,也更符合实际项目习惯。
db/models.py:数据库模型层这个文件定义了数据库表结构。
当前项目里定义了一个 User 表:
idnameage这里使用的是 SQLAlchemy ORM。
ORM 的好处是:你可以用 Python 类去操作数据库,而不是每次都手写 SQL。
db/database.py:数据库连接层这个文件负责数据库连接和会话管理,主要包括:
engineSessionLocalBaseget_db()这里的 get_db() 非常重要,因为 FastAPI 经常会通过依赖注入把数据库会话传给接口函数。
core/config.py:配置层这个文件目前比较简单,只定义了一个 Settings 类和应用名。
虽然现在内容不多,但在真实项目里,这里通常会扩展成:
所以这个目录可以理解为“给项目未来扩展预留的位置”。
我们以“新增用户”为例,来看一次请求的流转过程。
当前端发送请求:
POST /users/add
它在后端大致会经历下面这条链路:
main.py 创建的 FastAPI 应用/users 相关请求转发到 api/user.pyapi/user.py 中的 create_user 接口接收请求数据schemas/user.py 里的 UserCreate 校验请求体Depends(get_db) 从 db/database.py 获取数据库会话db/models.py 中的 User 模型创建数据库对象schemas/user.py 中的 User 模型格式化输出这样分层之后,项目结构会很清晰:
api 负责接请求schemas 负责校验数据models 负责映射数据库表database 负责连接数据库main 负责把这些模块组织起来下面是这个项目的完整核心代码。
app/main.pyfrom fastapi import FastAPI
from app.api import user
from app.db.database import engine
from app.db import models
app = FastAPI(title="Demo API")
app.include_router(user.router)
# 创建表
models.Base.metadata.create_all(bind=engine)
@app.get("/")
def root():
return {"msg": "FastAPI Template Running"}
app/run.pyimport uvicorn
if __name__ == "__main__":
uvicorn.run("app.main:app", host="127.0.0.1", port=8001, reload=False)
app/api/user.pyfrom fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.db.database import get_db
from app.db.models import User
from app.schemas.user import UserCreate, UserUpdate, User as UserSchema
from typing import List
router = APIRouter(prefix="/users", tags=["users"])
# 创建用户
@router.post("/add", response_model=UserSchema)
def create_user(user: UserCreate, db: Session = Depends(get_db)):
db_user = User(name=user.name, age=user.age)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
# 查询用户
@router.get("/list", response_model=List[UserSchema])
def get_users(db: Session = Depends(get_db)):
users = db.query(User).all()
return users
@router.delete("/{user_id}")
def delete_user(user_id: int, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.id == user_id).first()
if not db_user:
raise HTTPException(status_code=404, detail="用户不存在")
db.delete(db_user)
db.commit()
return {"msg": "删除成功"}
@router.put("/{user_id}", response_model=UserSchema)
def update_user(user_id: int, user: UserUpdate, db: Session = Depends(get_db)):
db_user = db.query(User).filter(User.id == user_id).first()
if not db_user:
raise HTTPException(status_code=404, detail="用户不存在")
db_user.name = user.name
db_user.age = user.age
db.commit()
db.refresh(db_user)
return db_user
app/db/database.pyfrom sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:baba12580@localhost:3306/pysql"
# 创建引擎
engine = create_engine(
SQLALCHEMY_DATABASE_URL,
)
# 会话工厂
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Base类(模型继承用)
Base = declarative_base()
# 依赖注入用
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
app/db/models.pyfrom sqlalchemy import Column, Integer, String
from app.db.database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String, index=True)
age = Column(Integer)
app/schemas/user.pyfrom pydantic import BaseModel, ConfigDict
class UserBase(BaseModel):
name: str
age: int
class UserCreate(UserBase):
pass
class UserUpdate(UserBase):
pass
class User(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
name: str
age: int
app/core/config.pyclass Settings:
app_name: str = "FastAPI Demo"
settings = Settings()
app/requirements.txt注意,这个文件按当前项目实际代码来看还不完整。
因为项目里已经使用了 sqlalchemy 和 pymysql,所以建议你写成下面这样:
fastapi
uvicorn
pydantic
sqlalchemy
pymysql
先进入项目根目录,然后执行:
..venvScriptspip.exe install -r .apprequirements.txt
如果你还没有虚拟环境,也可以先创建:
python -m venv .venv
..venvScriptsActivate.ps1
pip install -r .apprequirements.txt
uvicorn app.main:app --reload --port 8001
启动成功后,可以访问:
对于新手来说,/docs 非常友好,因为你可以直接在网页里测试接口。
如果你第一次学 FastAPI,我建议按下面顺序看代码:
先看 main.py
先知道项目从哪里启动、路由怎么注册。
再看 api/user.py
先看接口长什么样,理解 FastAPI 最直观的用法。
然后看 schemas/user.py
理解请求参数和响应数据是怎么校验的。
再看 db/models.py
知道数据库表是怎么定义的。
最后看 db/database.py
理解数据库连接和会话是怎么传到接口里的。
这个顺序会比一上来就看数据库配置更容易理解。
当你把这个小项目跑通之后,可以继续尝试加这些功能:
.envcore/config.py 改成真正的配置中心这些扩展做完之后,你对 FastAPI 的理解会更扎实。
对于新手来说,学 FastAPI 最重要的不是一开始就追求复杂功能,而是先看懂一个最小可运行项目的结构。
通过这个示例,你至少应该掌握下面几件事:
api、schemas、db 分别负责什么当你把这些最基础的结构搞明白后,后面再学用户认证、数据库迁移、异步接口、项目部署,就会轻松很多。
如果你愿意,我下一步可以继续帮你补两样内容中的一个:
100字摘要 + 结尾总结