# 同步编程模型 :::tip 核心原则 Flask 基于 WSGI 同步框架,所有视图函数和业务代码均为同步 `def`。通过多线程/多进程实现并发,代码简洁直观,调试方便。 ::: ## Flask 的执行模型 Flask 采用同步编程模型,所有请求处理在独立的线程中执行: ``` 客户端请求 ↓ WSGI 服务器(Gunicorn / Flask 内置) ↓ 分配线程处理请求 ↓ Flask 路由分发 → 视图函数 → Service → Repository → 数据库 ↓ 返回响应(同步等待完成) ``` 所有业务代码均为同步 `def`,数据库操作通过 SQLAlchemy 同步 ORM 完成,Redis 操作通过同步客户端完成。 ## 为什么选择同步模型 | 考量 | 说明 | |:---|:---| | **成熟稳定** | Flask 同步模型经过长期验证,生态完善 | | **代码简洁** | 直接调用,无异步包装开销 | | **调试方便** | 标准 Python 调试工具(pdb)直接可用 | | **学习曲线** | 同步编程更直观,团队上手快 | | **后台管理** | CRUD 为主的场景,同步模型完全够用 | ## 代码示例:全同步模式 ### Router 层 ```python # src/modules/system/position/router.py from flask import Blueprint, request from src.core.permission import check_permission from src.modules.system.position import service as position from src.common.utils.request import parse_request_body from src.core import response as R position_blue = Blueprint('position', __name__, url_prefix='/position') @position_blue.route('/page', methods=["GET"]) @check_permission("sys:position:page") def page(): """ 查询岗位分页数据 同步函数:直接调用 service,无需 await。 """ return R.ok(data=position.get_position_page(request.args)) @position_blue.route('/add', methods=["POST"]) @check_permission("sys:position:add") def add(): """ 添加岗位 同步函数:解析请求体 → 调用 service → 返回结果。 """ json_data, err = parse_request_body() if err: return R.failed(msg=err) position.add_position(json_data) return R.ok(msg="添加成功") ``` ### Service 层 ```python # src/modules/system/position/service.py from src.common.base_service import BaseService from src.core.exceptions import BizError from src.modules.system.position.schema import PositionForm, PositionStatusForm from src.modules.system.position.repository import PositionRepository from src.modules.system.user.repository import UserRepository class PositionService(BaseService): """ 岗位服务类 所有方法均为同步 classmethod,直接调用 Repository 访问数据库。 """ repository = PositionRepository form = PositionForm status_form = PositionStatusForm model_name = "岗位" @classmethod def before_delete(cls, ids): """删除前校验:检查用户引用""" for pid in ids: if UserRepository.count_by({'position_id': pid}) > 0: raise BizError(f"岗位ID {pid} 已被用户引用,无法删除") # 模块级代理函数 get_position_page = PositionService.get_page add_position = PositionService.add ``` ### Repository 层 ```python # src/modules/system/position/repository.py from src.common.base_repository import BaseRepository from src.common.constants.common import PAGE_SIZE from src.modules.system.position.models import Position class PositionRepository(BaseRepository): """岗位数据仓储,所有查询方法均为同步 classmethod""" model = Position @classmethod def page(cls, params: dict): """分页查询:直接调用基类 find_page,同步执行""" return cls.find_page( page=int(params.get('pageNo', 1)), page_size=int(params.get('pageSize', PAGE_SIZE)), filters={'status': params.get('status')}, like_filters={'name': params.get('name')}, order_by='sort', ) ``` :::tip 全链路同步 从 Router → Service → Repository → 数据库,全链路均为同步调用,代码简洁直观。 ::: ## Redis 操作也是同步的 项目使用 `redis-py` 同步客户端,所有 Redis 操作也是同步的: ```python # src/core/redis_client.py from redis import Redis redis = Redis.from_url(REDIS_URL, decode_responses=True) ``` ```python # 使用示例(同步) from src.core.redis_client import redis # 存储验证码 redis.set(f"captcha:{key}", code, ex=300) # 查询验证码 cached_code = redis.get(f"captcha:{key}") # 登录失败计数 count = redis.incr(f"login:fail:{ip}:{username}") redis.expire(f"login:fail:{ip}:{username}", 300) ``` ## 总结 项目采用 Flask 同步架构,全链路(Router → Service → Repository → Redis → 数据库)均为同步 `def`,代码简洁直观。通过 WSGI 服务器的多线程/多进程模型实现并发处理,对于后台管理系统场景完全够用。