Python学习:年轻人的第一个入门Python项目(FastAPI版)

2 阅读8分钟

入门python时,如果想先搭一个后端项目Demo练手,我建议使用FastAPI作为框架。

很多新手第一次接触 FastAPI 时,常见困惑不是“接口怎么写”,而是:

  • 项目目录为什么要这样分?
  • apischemasdb 分别是干什么的?
  • 一个请求到底会经过哪些文件?
  • 自己要怎么从 0 搭出一个能跑的项目?

这篇文章我会结合一个真实的 FastAPI 小项目,带你快速看懂它的目录结构、每个模块的职责,以及它们之间是怎么配合工作的。文章最后还会贴上完整代码,方便直接上手练习。

一、这个 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

image.png

如果你是第一次看这种结构,可以先这样理解:

  • main.py:应用主入口,负责创建 FastAPI 实例、注册路由
  • run.py:启动脚本,用来运行项目
  • api/:放接口路由,也就是你写 get/post/delete/put 的地方
  • schemas/:放请求和响应的数据结构,用 Pydantic 做数据校验
  • db/:放数据库相关代码,包括数据库连接和 ORM 模型
  • core/:放全局配置、公共设置
  • requirements.txt:项目依赖列表

对于新手来说,先记住一句话就够了:

FastAPI 常见项目结构,本质上就是把“接口、数据校验、数据库、配置”分开放。

三、每个模块分别是干什么的?

1. main.py:项目总入口

main.py 的职责通常有 3 个:

  • 创建 FastAPI 应用对象
  • 注册路由
  • 做一些初始化工作,比如创建数据库表

在这个项目里,它做了这些事:

  • 创建了 FastAPI(title="Demo API")
  • 注册了 user 路由
  • 启动时自动创建数据表
  • 提供了一个根路径 / 测试接口

也就是说,main.py 更像整个项目的“总装配中心”。

2. run.py:项目启动脚本

run.py 的作用是帮你更方便地启动服务。

它内部调用了 uvicorn.run(...),指定了:

  • 应用入口:app.main:app
  • 主机地址:127.0.0.1
  • 端口:8001

这样你就不用每次手动敲很长的 uvicorn 命令了。

3. api/user.py:接口层

这里是项目里最接近“业务功能”的部分,主要负责定义接口。

当前文件里有 4 个接口:

  • POST /users/add:新增用户
  • GET /users/list:查询用户列表
  • DELETE /users/{user_id}:删除用户
  • PUT /users/{user_id}:更新用户

这一层主要处理的是:

  • 路由路径
  • 请求方法
  • 请求参数
  • 响应格式
  • 错误处理

你可以把它理解成“前端和后端交互的入口”。

4. schemas/user.py:数据校验层

FastAPI 很重要的一个特点,就是它和 Pydantic 配合得很好。

这个文件里定义了几个数据模型:

  • UserBase:用户基础字段
  • UserCreate:创建用户时使用
  • UserUpdate:更新用户时使用
  • User:返回给前端的用户数据结构

为什么要单独拆一个 schemas 目录?

因为数据库模型和接口入参/出参不一定完全一样。
把它们分开写,会更清晰,也更符合实际项目习惯。

5. db/models.py:数据库模型层

这个文件定义了数据库表结构。

当前项目里定义了一个 User 表:

  • id
  • name
  • age

这里使用的是 SQLAlchemy ORM。
ORM 的好处是:你可以用 Python 类去操作数据库,而不是每次都手写 SQL。

6. db/database.py:数据库连接层

这个文件负责数据库连接和会话管理,主要包括:

  • 创建数据库引擎 engine
  • 创建会话工厂 SessionLocal
  • 创建 ORM 基类 Base
  • 提供依赖注入函数 get_db()

这里的 get_db() 非常重要,因为 FastAPI 经常会通过依赖注入把数据库会话传给接口函数。

7. core/config.py:配置层

这个文件目前比较简单,只定义了一个 Settings 类和应用名。

虽然现在内容不多,但在真实项目里,这里通常会扩展成:

  • 数据库地址
  • Redis 地址
  • JWT 密钥
  • 环境变量配置
  • 调试模式开关

所以这个目录可以理解为“给项目未来扩展预留的位置”。

四、一个请求是怎么走完整个项目的?

我们以“新增用户”为例,来看一次请求的流转过程。

当前端发送请求:

POST /users/add

它在后端大致会经历下面这条链路:

  1. 请求先进入 main.py 创建的 FastAPI 应用
  2. 应用把 /users 相关请求转发到 api/user.py
  3. api/user.py 中的 create_user 接口接收请求数据
  4. FastAPI 用 schemas/user.py 里的 UserCreate 校验请求体
  5. 接口通过 Depends(get_db)db/database.py 获取数据库会话
  6. 使用 db/models.py 中的 User 模型创建数据库对象
  7. 提交到数据库后,再返回给前端
  8. 响应内容再通过 schemas/user.py 中的 User 模型格式化输出

这样分层之后,项目结构会很清晰:

  • api 负责接请求
  • schemas 负责校验数据
  • models 负责映射数据库表
  • database 负责连接数据库
  • main 负责把这些模块组织起来

五、完整代码

下面是这个项目的完整核心代码。

1. app/main.py

from 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"}

2. app/run.py

import uvicorn

if __name__ == "__main__":
    uvicorn.run("app.main:app", host="127.0.0.1", port=8001, reload=False)

3. app/api/user.py

from 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

4. app/db/database.py

from 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()

5. app/db/models.py

from 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)

6. app/schemas/user.py

from 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

7. app/core/config.py

class Settings:
    app_name: str = "FastAPI Demo"

settings = Settings()

8. app/requirements.txt

注意,这个文件按当前项目实际代码来看还不完整。
因为项目里已经使用了 sqlalchemypymysql,所以建议你写成下面这样:

fastapi
uvicorn
pydantic
sqlalchemy
pymysql

六、怎么运行这个项目?

1. 安装依赖

先进入项目根目录,然后执行:

.\.venv\Scripts\pip.exe install -r .\app\requirements.txt

如果你还没有虚拟环境,也可以先创建:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r .\app\requirements.txt

2. 启动项目

uvicorn app.main:app --reload --port 8001

启动成功后,可以访问:

  • 首页:http://127.0.0.1:8001/
  • Swagger 文档:http://127.0.0.1:8001/docs

对于新手来说,/docs 非常友好,因为你可以直接在网页里测试接口。

七、新手如何快速理解这个项目?

如果你第一次学 FastAPI,我建议按下面顺序看代码:

  1. 先看 main.py 先知道项目从哪里启动、路由怎么注册。

  2. 再看 api/user.py 先看接口长什么样,理解 FastAPI 最直观的用法。

  3. 然后看 schemas/user.py 理解请求参数和响应数据是怎么校验的。

  4. 再看 db/models.py 知道数据库表是怎么定义的。

  5. 最后看 db/database.py 理解数据库连接和会话是怎么传到接口里的。

这个顺序会比一上来就看数据库配置更容易理解。

八、这个项目还能怎么继续扩展?

当你把这个小项目跑通之后,可以继续尝试加这些功能:

  • 用户详情接口
  • 按 ID 查询用户
  • 用户名唯一校验
  • 分页查询
  • 数据库配置读取 .env
  • core/config.py 改成真正的配置中心
  • 加登录认证
  • 按“路由层 + service 层 + dao 层”继续拆分

这些扩展做完之后,你对 FastAPI 的理解会更扎实。

九、结语

对于新手来说,学 FastAPI 最重要的不是一开始就追求复杂功能,而是先看懂一个最小可运行项目的结构。

通过这个示例,你至少应该掌握下面几件事:

  • FastAPI 项目通常怎么分目录
  • apischemasdb 分别负责什么
  • 请求是怎么从路由走到数据库的
  • 一个基础的增删改查接口项目如何搭建

当你把这些最基础的结构搞明白后,后面再学用户认证、数据库迁移、异步接口、项目部署,就会轻松很多。

如果你愿意,我下一步可以继续帮你补两样内容中的一个:

  1. 给这篇博客再配一个 100字摘要 + 结尾总结
  2. 继续升级成“带接口测试截图说明”的发文版本