企业级的项目框架搭建

发布时间:2026/7/22 8:13:10
企业级的项目框架搭建 之前发布的是一个简单的 FastAPI 框架搭建用于初学者学习或简单业务场景下面是一个标准版的企业级项目架构。1. 项目结构规划项目根目录/ ├── main.py # FastAPI 应用主入口 ├── requirements.txt # Python 依赖包 └── app/ # 应用核心代码 ├── __init__.py ├── core/ # 核心工具层 │ ├── __init__.py │ └── database.py # 数据库连接信息 ├── config/ # 配置文件 │ ├── __init__.py │ └── settings.py # 多环境配置 ├── models/ # 数据模型层 (Tortoise ORM) │ ├── __init__.py │ └── user.py # 用户相关模型 ├── schemas/ # 数据验证层 (Pydantic) │ ├── __init__.py │ └── user.py # 用户请求/响应模型 ├── services/ # 业务服务层 (逻辑) │ ├── __init__.py │ └── user.py # 用户相关的业务代码/方法 └── apis/ # API 路由层 ├── __init__.py └── user_api.py # 用户相关 API这套是后端行业通用的分层解耦架构核心思想各司其职、分层隔离修改一处逻辑不会牵连其他代码方便维护、单元测试、多人协作。一、根目录文件全局入口与依赖1.main.py项目启动入口整个项目的程序起点作用实例化 FastAPIapp对象加载数据库、中间件CORS、TrustedHost、日志注册所有路由引入apis下的接口蓝图启动服务入口uvicorn 运行时指定此文件2.requirements.txt依赖清单记录项目所有第三方包一键安装环境pip install -r requirements.txt二、app/ 业务核心文件夹所有业务代码统一收纳1.core/底层核心工具层公共基础能力存放项目全局通用、底层支撑代码和具体业务无关database.pyTortoise-ORM 数据库初始化、DB_URL 连接串、数据库注册配置全局只初始化一次数据库连接。2.config/settings.py多环境配置中心统一管理项目所有配置项区分开发 / 测试 / 生产环境数据库地址、账号密码、库名跨域开关、密钥、JWT 过期时间、日志级别环境变量读取.env文件配套使用好处所有配置集中一处换数据库、改线上地址只改这里不用到处改代码。3.models/数据库模型层Tortoise ORM直接映射 MySQL 数据表和数据库一一对应user.pyUser(models.Model)定义表字段、主键、索引、表注释职责只描述数据表结构不写业务逻辑、不处理接口参数数据流向服务层services调用 models 做增删改查4.schemas/Pydantic 数据校验层接口入参 / 出参模板专门处理 HTTP 请求的数据校验、格式化返回请求 Schema前端传过来的参数校验用户名长度、密码格式、必填项响应 Schema控制接口返回给前端的字段隐藏数据库敏感字段如 password和models区分models 管数据库schemas 管前后端接口数据两者解耦。5.services/业务逻辑层核心业务处理所有复杂业务逻辑写在这里apis 只负责接收请求不写逻辑user.py用户注册、登录、密码加密、查询用户、分页查询等逻辑分层优势接口层极简相同业务可被多个接口复用方便单独写单元测试。6.apis/接口路由层请求入口只做三件事禁止写复杂逻辑接收前端 HTTP 请求拿到schemas校验后的参数调用services业务函数处理数据把业务返回结果用schemas格式化后返回给前端按业务拆分文件user_api.py只存放用户相关接口路由分组管理。三、完整数据请求流程从头到尾走一遍用户登录前端请求 →apis/user_api.py→schemas校验参数 →services/user.py登录逻辑 →models/user.py查询数据库 → 原路组装数据返回前端前端 POST 登录接口apis接收请求用schemas.LoginReq校验用户名密码格式调用services.user.login(username, password)service 内部通过models.User.get()查询数据库用户密码比对、生成 token 等业务逻辑完成service 返回用户信息apis 通过schemas.UserResp过滤敏感字段返回 JSON四、分层设计的核心优势低耦合改数据库表结构只动 models改参数校验只动 schemas改登录逻辑只动 service易维护业务清晰新人上手能快速找到对应代码可复用同一个查询用户逻辑多个接口都能调用 service 方法便于测试业务逻辑单独抽离 service可脱离接口写单元测试规范统一团队开发强制分层不会出现逻辑到处散落的混乱代码2. 数据库配置在app/core/database.py,添加代码:# app/core/database.py 数据库配置文件 这个文件定义了 Tortoise-ORM 连接 MySQL 数据库所需的所有配置信息 from app.config.settings import settings # TORTOISE_ORM 是 Tortoise-ORM 规定的配置字典变量名 # 后面用 register_tortoise 或 Aerich 时都会引用这个字典 TORTOISE_ORM { # 1. 连接配置 —— 定义数据库连接信息 connections: { # default 是默认连接的名字必须有一个 default default: { # engine指定数据库后端引擎MySQL 使用 tortoise.backends.mysql engine: tortoise.backends.mysql, # credentials数据库连接凭证包含主机、端口、用户名、密码等 credentials: { host: 127.0.0.1, # MySQL 服务器地址 port: 3306, # MySQL 端口默认 3306 user: root, # 数据库用户名 password: 123456, # 数据库密码请根据实际情况修改 database: fastapi_db0719, # 数据库名称 minsize: 1, # 连接池最小连接数 maxsize: 5, # 连接池最大连接数 charset: utf8mb4, # 字符集支持 emoji echo: True # 是否打印 SQL 语句开发环境建议开启 } } }, # 2. 应用配置 —— 指定模型所在的模块 apps: { # models 是应用的名字可以自定义但 Aerich 需要使用这个名字 models: { # models 列表指定包含 Tortoise 模型类的 Python 模块路径 # aerich.models 是 Aerich 的内置模型用于记录迁移历史必须包含 models: [app.models, aerich.models], # default_connection指定这个应用使用哪个数据库连接 default_connection: default, } }, # 3. 时区配置 use_tz: False, # 是否使用时区 timezone: Asia/Shanghai, # 时区设置 echo: True # ✅ 关键打开 SQL 打印 }在main.py,加载数据库配置from contextlib import asynccontextmanager from fastapi import FastAPI from tortoise import Tortoise from app.config.settings import settings from app.core.database import TORTOISE_ORM asynccontextmanager async def lifespan(app: FastAPI): await Tortoise.init(configTORTOISE_ORM, _enable_global_fallbackTrue) print(数据库连接启动成功) yield await Tortoise.close_connections() print(数据库连接已关闭) app FastAPI( titlesettings.app_title, versionsettings.app_version, descriptionsettings.app_description, lifespanlifespan )lifespan异步生命周期函数lifespan是 FastAPI 的项目生命周期钩子分两段执行yield之前项目启动时执行服务刚启动接收请求前yield之后项目关闭时执行服务停止不再接收请求asynccontextmanager async def lifespan(app: FastAPI): # 启动阶段服务初始化 # 初始化 Tortoise ORM建立数据库连接池 await Tortoise.init(configTORTOISE_ORM, _enable_global_fallbackTrue) print.debug(数据库连接启动成功) yield # 分界线服务正式开始运行接收前端所有接口请求 # 关闭阶段服务销毁 # 安全关闭所有数据库连接释放资源 await Tortoise.close_connections() print(数据库连接已关闭)关键参数说明configTORTOISE_ORM传入数据库配置库地址、账号、模型注册路径_enable_global_fallbackTrue开启全局 ORM 实例全项目任意地方都能直接使用User.get()等模型查询不用额外传连接对象作用优势自动建连接启动服务时自动连上数据库不用手动执行初始化脚本安全释放资源服务关闭时主动断开数据库连接避免连接泄漏、数据库挂死统一管理初始化逻辑后续要加 Redis、日志、定时任务都可以写在yield上方⚠️ 小问题print.debug()会直接报错Python 内置 print 没有 debug 方法替换为print(数据库连接启动成功)或者使用日志工具logger.debug()三、FastAPI 实例创建pythonapp FastAPI( titlesettings.app_title, # 接口文档标题来自配置文件 versionsettings.app_version, # 项目版本号 descriptionsettings.app_description, # 接口文档描述 lifespanlifespan # 绑定上面写好的生命周期函数 )前三个参数作用自动生成/docs、/redoc接口文档页面的展示文字统一在settings.py配置方便区分开发 / 生产环境文档说明。lifespanlifespan把生命周期钩子绑定到应用让框架自动执行数据库初始化和关闭逻辑。四、完整执行流程启动 / 关闭服务全过程1. 启动服务uvicorn main:app代码从上往下执行创建app对象FastAPI 自动调用lifespan函数执行await Tortoise.init()→ 连接数据库走到yield暂停生命周期函数服务启动完成开始监听端口、接收前端请求2. 停止服务CtrlC框架收到停止信号回到yield下方代码执行await Tortoise.close_connections()→ 关闭所有数据库连接打印关闭日志服务彻底退出3. 配置跨域在项目入口main.py 中配置跨域设置app.add_middleware( CORSMiddleware, allow_origins[*], # 允许所有源生产环境改为指定域名列表 allow_credentialsTrue, # 允许携带Cookie/Token allow_methods[*], # 允许所有请求方法 allow_headers[*], # 允许所有请求头 )3.1 什么是跨域浏览器有同源策略安全限制 只有同时满足下面 3 点才算同源浏览器允许前端直接请求后端接口协议相同http/https域名 / IP 相同端口号相同任意一项不一样就属于跨域请求浏览器会拦截返回数据控制台报 CORS 错误。3.2 参数详解3.2 参数详解allow_origins[*]开发环境临时用允许所有前端地址生产环境必须写真实域名[https://你的前端网站.com]不能用*否则allow_credentialsTrue会失效。allow_credentialsTrue前端登录后要带 Token、Cookie 登录态时必须开启。allow_methods[*]放行所有 HTTP 请求方法否则 POST、PUT 等请求会被拦截。跨域问题主要出现在前后端分离的场景,当前后端互相调用的时候就会出现这个问题.